Connecting multiple Couchbase buckets in a Spring Application
In this article, we will look at how to connect to 2 different buckets in the same cluster on Couchbase by using the AbstractCouchbaseConfiguraton
interface.
Creating the Buckets
Firstly, we create Company and Employee buckets in the Couchbase cluster and then we create indexes for each bucket on their id properties by executing the following commands;
CREATE INDEX `idx_company_id` ON `Company`(META().`id`);
CREATE INDEX `idx_employee_id` ON `Employee`(META().`id`);
After creating the indexes, as one user for each bucket, we create Company and Employee users to connect those buckets. We open localhost:8091
on the browser and go to the Security tab at the left panel, we add the users with the exact same name with the Bucket name. Also, we set a password for each bucket that will be used at the Java application for connecting the buckets.
Adding dependency and defining the connection information
After finishing the steps we should do in the Couchbase cluster, firstly, we add the following libraries needed to the pom.xml
file.
Then, we define the user information in the application. Thus, we add the following information to the application.yaml
file. There are 2 different connection information;
- the first connection information under the
bucket-company
belongs to the user that will be used to access the Company bucket - the second connection information under the
bucket-employee
belongs to the user that will be used to access the Employee bucket
couchbase:
connection-string: couchbase://127.0.0.1
user-name: admin
password: 123456
bucket-company:
name: Company
user-name: Company
password: com123
bucket-employee:
name: Employee
user-name: Employee
password: emp123
Creating Document Model classes
We open the model package at the root directory and create the Company and Employee class as Couchbase document model under it. A class should be pointed as a Couchbase document model by theDocument
annotation at above class definition.
In the example below, the GeneratedValue
annotation provides the rule to be set id that to be needed to keep a document in a bucket. The USE_ATTRIBUTES
parameter means that the fields, which are marked with IdAttribute
annotation, and combined them with #
or -
delimiters according to the order defined.
For Company object, id will be set as companyName#location
format
For Employee object, id will be set as name-surname
format
Creating Configuration classes
We open the configuration package at the root directory and create the following classes to take the configuration parameters above and create the bucket connection;
The naming standard is important in here because the configuration define as kebab-case in the
application.yaml
file and in the following classes variable names should be camel-case version of what we defined.
The “CouchbaseBucketProperties” class
This class encounters the bucket properties (i.e. name, user-name, and password) under the bucket-company parameter in the application.yaml
file above.
The “CouchbaseClusterProperties” class
This class encounters the cluster properties (i.e. connection-string, user-name, password, bucket-company, and bucket-employee) under the couchbase parameter in the application.yaml
file above. Also, the couchbase parameter is declared as the prefix of the ConfigurationProperties
annotation to get properties properly.
The “CouchbaseBucketConfiguration” class
This class is used to open the Couchbase connection with the configuration defined. We should be extended from theAbstractCouchbaseConfiguraton
interface so there are 4 methods that should be overridden.
If we have one bucket to connect, we can open a connection to this bucket with call the bucket information inside these 4 methods.
In this article, we focus on how to add the second bucket to the project. Therefore, we add employeeClientFactory
and employeeTemplate
beans to set Employee bucket configurations. The employeeTemplate
is used in the configureRepositoryOperationsMapping
method that will be overridden in here to map Document Model class and template of bucket related with this model class. We set Employee class to the Employee bucket in here.
Creating Repository interfaces
We open the repository package at the root directory and create the CompanyRepository and EmployeeRepository interfaces extended from CrudRepository that provides CRUD operations (save, delete, …) for the Couchbase methods properly and it automatically defines basic CRUD operations when we implement it, so there is no need to implement any other function here.
The only thing we should do is defining the type of CrudRepository as Company or Employee according to the bucket we want. Since we map all Document Model classes with a bucket template at the previous step, the repository class will connect to the Company bucket below
public interface CompanyRepository extends CrudRepository<Company, String> { }
On the other hand, we define Employee object to CrudRepository to connect the repository class below to the Employee bucket.
public interface EmployeeRepository extends CrudRepository<Employee, String> { }
Creating Service & Controller class
Everything we need for connecting to Couchbase was done, and we are ready to implement Java SDK to our application. We open the service package at the root directory and create the CouchbaseService class.
There are only 2 methods here and these methods basically convert the request model to a Document Model and save it to a bucket. To save the document into the related bucket, both CompanyRepository and EmployeeRepository classes are injected in this class, and the save method of each repository is called.
To trigger these service methods from Swagger, we create the CouchbaseController class and open 2 endpoints, one for the Company document, one for the Employee document.
Checking the Results
Now, we are ready for interacting with the Couchbase so we run the project, open the Swagger on the http://localhost:9292/swagger-ui.html#/
, and check these 2 endpoints below.
Then we test the endpoints;
- The
insertCompany
method is executed (by POST method) with the{ "companyName”: “TYG", “location": "İstanbul", “size": 1800 }
object, the following document saved in the Company bucket.
- The
insertEmployee
method is executed (by POST method) with the{ "name”: “John", “surname": "Doe" }
object, the following document saved in the Employee bucket.
The java project, which contains all code we implemented at the steps above, is available here.