Boot

Spring Boot Application with Couchbase

Welcome, in this tutorial, we will see how to configure a spring boot application to use the couchbase bucket for storing information using spring data.

1. Introduction

Before going further in this tutorial, we will look at the common terminology such as introduction to Spring Boot, Couchbase db, and Lombok.

1.1 Spring Boot

  • Spring boot is a module that provides rapid application development feature to the spring framework including auto-configuration, standalone-code, and production-ready code
  • It creates applications that are packaged as jar and are directly started using embedded servlet container (such as Tomcat, Jetty or, Undertow). Thus, no need to deploy the war files
  • It simplifies the maven configuration by providing the starter template and helps to resolve the dependency conflicts. It automatically identifies the required dependencies and imports them into the application
  • It helps in removing the boilerplate code, extra annotations, and xml configurations
  • It provides powerful batch processing and manages the rest endpoints
  • It provides an efficient jpa-starter library to effectively connect the application with the relational databases
  • It offers a Microservice architecture and cloud configuration that manages all the application related configuration properties in a centralized manner

1.2 Couchbase db

  • Couchbase db is an open-source, distributed multi-model NoSQL document-oriented database
  • Spring boot framework provides automatic configuration for the couchbase db via the spring-boot-starter-data-couchbase dependency
  • Couchbase db provides a bucket for storing the information in the JSON format
  • By default, couchbase db starts at port 8091

1.3 Lombok

  • Lombok is nothing but a small library that reduces the amount of boilerplate Java code from the project
  • Automatically generates the getters and setters for the object by using the Lombok annotations
  • Hooks in via the Annotation processor API
  • Raw source code is passed to Lombok for code generation before the Java Compiler continues. Thus, produces properly compiled Java code in conjunction with the Java Compiler
  • Under the target/classes folder you can view the compiled class files
  • Can be used with Maven, Gradle IDE, etc.

1.3.1 Lombok features

Feature Details
val Local variables are declared as final
var Mutable local variables
@Slf4J Creates an SLF4J logger
@Cleanup Will call close() on the resource in the finally block
@Getter Creates getter methods for all properties
@Setter Creates setter for all non-final properties
@EqualsAndHashCode
  • Generates implementations of equals(Object other) and hashCode()
  • By default will use all non-static, non-transient properties
  • Can optionally exclude specific properties
@ToString
  • Generates String of class name, and each field separated by commas
  • Optional parameter to include field names
  • Optional parameter to include a call to the super toString method
@NoArgsConstructor
  • Generates no-args constructor
  • Will cause compiler error if there are final fields
  • Can optionally force, which will initialize final fields with 0/false/null var – mutable local variables
@RequiredArgsContructor
  • Generates a constructor for all fields that are final or marked @NonNull
  • The constructor will throw a NullPointerException if any @NonNull fields are null val – local variables are declared final
@AllArgsConstructor
  • Generates a constructor for all properties of the class
  • Any @NotNull properties will have null checks
@Data
  • Generates typical boilerplate code for POJOs
  • Combines – @Getter, @Setter, @ToString, @EqualsAndHashCode, @RequiredArgsConstructor
  • No constructor is generated if constructors have been explicitly declared
@Builder
  • Implements the Builder pattern for object creation
@Value
  • The immutable variant of @Data
  • All fields are made private and final by default

Let us go ahead with the tutorial implementation but before going any further I’m assuming that you’re aware of the Spring boot basics.

2. Spring Boot Application with Couchbase

2.1 Application Pre-requisite

To start with this tutorial, I am hoping you have the couchbase up and running in your localhost environment. For easy setup, I have the couchbase up and running on the Docker environment. You can execute the below script using the docker-compose command to get the couchbase container running on Docker in minutes. If you’re doing it for the first time the docker image will be downloaded from the docker hub.

docker-compose.yml

services:
  couchbase:
    container_name: couchbase
    image: couchbase
    ports:
      - '8091:8091'
      - '8092:8092'
      - '8093:8093'
      - '8094:8094'
      - '11210:11210'
version: '3.7'

If everything goes well the couchbase server container would be started successfully as shown in Fig. 1. You can use the docker ps -a command to confirm that the container is started successfully. For further information on docker basics, you can navigate to this tutorial.

Fig. 1: Couchbase server container on Docker

2.2 Tools Used for Spring boot application and Project Structure

We are using Eclipse Kepler SR2, JDK 8, and Maven. In case you’re confused about where you should create the corresponding files or folder, let us review the project structure of the spring boot application.

Fig. 2: Project structure

Let us start building the application!

3. Setup Couchbase Server and Create a table

Once the couchbase server is up and running, head over to the administration console by typing the following address in the browser – http://localhost:8901/. The administration console will open as shown in Fig. 3.

Fig. 3: Couchbase server welcome page

Click on the Setup New Cluster button to set up the new cluster details for the couchbase server as shown in Fig. 4. Use any password of your choice but remember it as this same password will be used to access the couchbase server via the console.

Fig. 4: Enter the new cluster details

Once done click on the Next button to accept the terms. On the terms page, you will have an option to either finish with defaults or configure disk, memory, and services. In this tutorial, we will do a custom setup.

Fig. 5: Accepting the couchbase server terms

Uncheck the Analytics and Eventing checkboxes and click Save & Finish as shown in Fig. 6.

Fig. 6: Configuring couchbase server

Once done, you will be successfully logged in to the couchbase server. The first thing here is to set up a bucket for storing information. Click on the Buckets in the right navigation bar and go to the Add Bucket button. Add the details as shown in Fig. 7 and click the Add Bucket button.

Spring Boot Couchbase - Creating a new bucket
Fig. 7: Creating a new bucket

Once the bucket is successfully created we will need a user that can perform operations on the created bucket and this will the same user will be used in the spring boot application. Click on the Security in the right navigation bar and go to the Add User button. Add the details as shown in Fig. 8 and click the Add User button. Remember to keep the username as the bucket name and use the password of your choice but remember it as this same password will be used in the spring boot application.

Spring Boot Couchbase - Add new user
Fig. 8: Add new user

4. Creating a Spring Boot application

Below are the steps involved in developing the application.

4.1 Maven Dependency

Here, we specify the dependency for the Spring boot (Web and Couchbase), Java Faker, and Lombok. The updated file will have the following code.

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.6.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.springboot.couchbase</groupId>
    <artifactId>Springbootandcouchbase</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>Springbootandcouchbase</name>
    <description>Springboot and couchbase tutorial</description>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-couchbase</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!-- java-faker -->
        <dependency>
            <groupId>com.github.javafaker</groupId>
            <artifactId>javafaker</artifactId>
            <version>1.0.2</version>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

4.2 Application yml file

Create a new yml file at the location: Springbootandcouchbase/src/main/resources/ and add the following code to it. Here we will define the application and couchbase server configuration. Remember to enter the couchbase details that were used while setting up the couchbase server.

application.yml

logging:
  level:
    org.springframework.data.couchbase.repository.query: DEBUG
server:
  port: 9300
spring:
  application:
    name: springboot-couchbase
  couchbase:
    bootstrap-hosts: "127.0.0.1"
    bucket:
      name: jcgassignment
      password: password_1
  data:
    couchbase:
      auto-index: true

4.3 Java Classes

Let us write the important java class(es) involved in this application. For brevity, we will skip the following classes –

  • DefaultEmployeeLoader.java – Bootstrap class to populate dummy data to the couchbase bucket (named – jcgassignment) once the application is started successfully. You can use the get-all-employees endpoint to fetch all the employees
  • BeanConfig.java – Configuration class contains a @Bean annotated method that creates a Faker object during the application startup and will be automatically injected into the application
  • EmployeeService.java – Service class that provide some business facilities and interact with the DAO layer methods
  • EntityNotFound.java – Exception class to return the 404 status code if an item does not exist

4.3.1 Implementation/Main class

Add the following code to the main class to bootstrap the application from the main method. Always remember, the entry point of the spring boot application is the class containing @SpringBootApplication annotation and the static main method.

SpringbootandcouchbaseApplication.java

package com.springboot.couchbase;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

import lombok.extern.slf4j.Slf4j;

//lombok annotation
@Slf4j
//spring annotation
@SpringBootApplication
public class SpringbootandcouchbaseApplication {

	public static void main(String[] args) {
		SpringApplication.run(SpringbootandcouchbaseApplication.class, args);
		log.info("springboot and couchbase application started successfully");
	}
}

4.3.2 Entity class

Add the following code to the entity class and the class will be annotated with the @Document annotation.

Employee.java

package com.springboot.couchbase.entity;

import com.couchbase.client.java.repository.annotation.Field;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.data.annotation.Id;
import org.springframework.data.couchbase.core.mapping.Document;
import org.springframework.data.couchbase.core.mapping.id.GeneratedValue;
import org.springframework.data.couchbase.core.mapping.id.GenerationStrategy;

//lombok annotations
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
// identified the domain object to be persisted to couchbase
@Document
public class Employee {

    //identifies a field which will not be stored in the couchbase document but rather
    //used an document id
    @Id
    @GeneratedValue(strategy = GenerationStrategy.UNIQUE)
    String id;
    //denotes a field which in the couchbase document
    @Field(value = "full_name")
    String fullName;
    @Field
    int age;
    @Field(value = "phone_number")
    String phoneNumber;
    @Field
    String address;
    @Field(value = "work_department")
    String workDepartment;
}

4.3.3 Repository interface

Add the following code to the repository interface to define the SQL CRUD functionality. The interface will be annotated with the couchbase server and the spring framework stereotype annotations.

EmployeeRepository.java

package com.springboot.couchbase.repository;

import java.util.List;

import org.springframework.data.couchbase.core.query.N1qlPrimaryIndexed;
import org.springframework.data.couchbase.core.query.ViewIndexed;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;

import com.springboot.couchbase.entity.Employee;

//couchbase annotations
@N1qlPrimaryIndexed
@ViewIndexed(designDoc = "employee")
//spring annotation
@Repository
public interface EmployeeRepository extends CrudRepository<Employee, String> {

	List<Employee> findAllByWorkDepartment(String workDepartment);
}

4.3.4 Controller class

Add the following code to the controller class. The class is injected with the service dependency whose method will call the DAO layer methods to fetch the data from the couchbase bucket (named – jcgassignment).

EmployeeController.java

package com.springboot.couchbase.controller;

import com.springboot.couchbase.entity.Employee;
import com.springboot.couchbase.exception.EntityNotFound;
import com.springboot.couchbase.service.EmployeeService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;

import java.util.List;

//lombok annotation
@Slf4j
//spring annotations
@RestController
@RequestMapping("/api")
public class EmployeeController {

    @Autowired
    EmployeeService service;

    //URL - http://localhost:9300/api/employees
    @GetMapping("/employees")
    @ResponseStatus(HttpStatus.OK)
    public List<Employee> getEmployees() {
        log.info("returning all employees from the couchbase");
        return service.getEmployees();
    }

    //URL - http://localhost:9300/api/employee/<eid>
    //Example - http://localhost:9300/api/employee/73a02968-70a8-426a-b6d8-deaa96a597df
    @GetMapping("/employee/{eid}")
    @ResponseStatus(HttpStatus.OK)
    public Employee getEmployeeById(@PathVariable String eid)
            throws EntityNotFound {
        log.info("returning employee id = {} from the couchbase", eid);
        return service.getEmployee(eid);
    }

    //URL - http://localhost:9300/api/employee/<work_department>
    //Example - http://localhost:9300/api/employees/Health
    @GetMapping("/employees/{work_department}")
    @ResponseStatus(HttpStatus.OK)
    public List<Employee> getEmployeeByWorkDepartment(@PathVariable(name = "work_department") String workDepartment) {
        log.info("returning employees from couchbase where work-department = {}", workDepartment);
        return service.getEmployeesByWorkDepartment(workDepartment);
    }

    //URL - http://localhost:9300/api/employees/count
    @GetMapping("/employees/count")
    @ResponseStatus(HttpStatus.OK)
    public long getTotalEmployees() {
        log.info("returning employees count from the couchbase");
        return service.count();
    }
}

5. Run the Application

To execute the application, right-click on the Springbootandcouchbase.java class, Run As -> Java Application.

Spring Boot Couchbase - run the app
Fig. 9: Run the Application

6. Project Demo

When the application is started, open the Postman tool to hit the application endpoints to fetch the data from the couchbase bucket. You are free to use any other tool of your choice to make the get requests to the endpoints.

Application endpoints

-- HTTP GET endpoint (to fetch all the employees) –
http://localhost:9300/api/employees

-- HTTP GET endpoint (to fetch all employees by work department) --
http://localhost:9300/api/employee/<work_department>

-- HTTP GET endpoint (to fetch employee by id) --
http://localhost:9300/api/employee/<eid>

-- HTTP GET endpoint (to fetch employees count) --
http://localhost:9300/api/employees/count

That is all for this tutorial and I hope the article served you whatever you were looking for. Happy Learning and do not forget to share!

7. Summary

In this section, you learned,

  • Spring boot, Lombok, and Couchbase server introduction
  • Steps to setup couchbase server on docker
  • Steps to create a bucket through couchbase gui
  • Steps to configure couchbase in a spring-boot application through spring data

You can download the sample application as an Eclipse project in the Downloads section.

8. Download the Project

This was an example of configuring the couchbase server in a spring boot application.

Download
You can download the full source code of this example here: Spring Boot Application with Couchbase

Yatin

An experience full-stack engineer well versed with Core Java, Spring/Springboot, MVC, Security, AOP, Frontend (Angular & React), and cloud technologies (such as AWS, GCP, Jenkins, Docker, K8).
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Inline Feedbacks
View all comments
Back to top button