Building Reactive REST CRUD APIs with Spring Boot, Spring WebFlux, Azure Cosmos DB and Azure Cosmos DB SQL API

Hello everyone, Hope you are doing well. In this tutorial, you will learn how to build reactive REST CRUD APIs with Spring Boot, Spring WebFlux, Azure Cosmos DB, and Azure Cosmos DB SQL API.



A little bit of Background

Azure Cosmos DB

Azure Cosmos DB is a fully managed NoSQL database for modern app development. Single-digit millisecond response times, and automatic and instant scalability, guarantee speed at any scale. 

Azure Cosmos DB SQL API

Azure Cosmos DB SQL API accounts provide support for querying items using the Structured Query Language (SQL) syntax.

Spring Boot

Spring Boot makes it easy to create stand-alone, production-grade Spring-based Applications that you can "just run". 

Spring WebFlux

The original web framework included in the Spring Framework, Spring Web MVC, was purpose-built for the Servlet API and Servlet containers. The reactive-stack web framework, Spring WebFlux, was added later in version 5.0. It is fully non-blocking, supports Reactive Streams back pressure, and runs on such servers as Netty, Undertow, and Servlet 3.1+ containers.


After completing this tutorial what we will build? 

We will build REST APIs  CRUD features: 




Step 1: Sign in to Azure Portal and create a resource group

Sign in to Azure portal https://portal.azure.com/#home and find "Resource groups" like below.



Then, create a resource group like the one below.


Here the resource group name is "Knowledgefactory". Create a resource group by clicking the "Review + create " button.




Step 2: Create an Azure Cosmos DB

Select "Azure Cosmos DB",


You will be taken to a page like the below image, Then click on the "Create Azure Cosmos DB account" button.

Select API Option,
Then click on the "create" button of the "Core (SQL) - Recommended" division.


Create Azure Cosmos DB Account - Core (SQL),
Enter/Select Resource groupAccount name, etc... Then click on the "Review + create" button.  

You will be taken to a page like the below image, 

Then click on the "Create" button.

Now, You can see "Deployment is in progress" like the below image.

Once deployment is completed you can see the "Your deployment is complete" page like the below image.

Then go to the "Keys" ,


You will be taken to a page like the below image, 
Copy the "URI" value and "PRIMARY KEY" value for future purpose.



Step 3: Add Container 

Click on the "Add Container" button.

Next enter "Database id", "Container id" etc...

Copy that "Database id" and "Container id" for future purpose.



Step 4: Creating a simple spring boot web application.

First, open the Spring initializr https://start.spring.io/

Then, Provide the Group and Artifact name. We have provided Group name com.knf.dev.demo and Artifact spring-webflux-azure-cosmos-db-sql-api-crud. Here I selected the Maven project - language Java - Spring Boot 2.7.1 and add Spring Reactive Web dependency and Azure Cosmos DB dependency



Then, click on the Generate button. When we click on the Generate button, it starts packing the project in a .zip(spring-webflux-azure-cosmos-db-sql-api-crud) file and downloads the project. 
Then, Extract the Zip file.



Step 5: Import the project on your favourite IDE, I am using Eclipse IDE

Import the project File -> Import -> Maven ->Existing Maven Project -> Next -> Browse -> Select the project -> Finish

Final Project Directory:



Pom.xml 

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
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.7.1</version>
<relativePath/>
</parent>
<groupId>com.knf.dev.demo</groupId>
<artifactId>
spring-webflux-azure-cosmos-db-sql-api-crud
</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>spring-webflux-azure-cosmos-db-sql-api-crud</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>17</java.version>
<spring-cloud-azure.version>
4.2.0
</spring-cloud-azure.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<dependency>
<groupId>com.azure.spring</groupId>
<artifactId>
spring-cloud-azure-starter-data-cosmos
</artifactId>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.projectreactor</groupId>
<artifactId>reactor-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.azure.spring</groupId>
<artifactId>
spring-cloud-azure-dependencies
</artifactId>
<version>${spring-cloud-azure.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>

<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>

</project>



application.yaml

Configure your Spring Boot application to use your Azure Cosmos DB
spring:
cloud:
azure:
cosmos:
database: <Database id>
populate-query-metrics: true
endpoint: <URI>
key: <PRIMARY KEY>


Create User Model

package com.knf.dev.demo.entity;

import org.springframework.data.annotation.Id;
import com.azure.spring.data.cosmos.core.mapping.Container;
import com.azure.spring.data.cosmos.core.mapping.GeneratedValue;

@Container(containerName = "User")
public class User {
@Id
@GeneratedValue
private String id;
private String firstName;
private String lastName;
private String email;

public User() {

}

public User(String firstName,
String lastName, String email) {

this.firstName = firstName;
this.lastName = lastName;
this.email = email;
}

public String getId() {
return id;
}

public void setId(String id) {
this.id = id;
}

public String getFirstName() {
return firstName;
}

public void setFirstName(String firstName) {
this.firstName = firstName;
}

public String getLastName() {
return lastName;
}

public void setLastName(String lastName) {
this.lastName = lastName;
}

public String getEmail() {
return email;
}

public void setEmail(String email) {
this.email = email;
}
}
  • @Id annotation is currently used by Spring to support mapping for other non-relational persistence databases or frameworks that do not have a defined common persistence API like JPA.
  • @ContainerAnnotation for Cosmos Container
  • @GeneratedValue: Used to specify that an entities id field should generate a value



Create Reactive User Repository

package com.knf.dev.demo.repository;

import com.azure.spring.data.cosmos
.repository.ReactiveCosmosRepository;
import com.knf.dev.demo.model.User;

public interface UserRepository
extends ReactiveCosmosRepository<User, String> {

}
The ReactiveCosmosRepository interface provides synchronous and reactive APIs for basic save, delete, and find operations.



Create Reactive Rest Controller

package com.knf.dev.demo.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.knf.dev.demo.model.User;
import com.knf.dev.demo.repository.UserRepository;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

@RestController
@RequestMapping("/api/v1/users")
public class UserController {

@Autowired
private UserRepository repository;

@GetMapping
Flux<User> getAll() {

return repository.findAll();
}

@GetMapping("/{id}")
Mono<User> getUser(@PathVariable("id") String id) {

return repository.findById(id);
}

@PostMapping
Mono<User> addUser(@RequestBody User user) {

return repository.save(user);
}

@PutMapping("/{id}")
private Mono<User> updateUser(@PathVariable("id")
String id, @RequestBody User user) {

return repository.findById(id).flatMap(user1 -> {
user.setId(id);
return repository.save(user);
}).switchIfEmpty(Mono.empty());
}

@DeleteMapping("/{id}")
Mono<Void> deleteById(@PathVariable("id") String id) {

return repository.findById(id)
.flatMap(p -> repository.deleteById(p.getId()));
}
}



Spring Boot Main Driver

package com.knf.dev.demo;

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

@SpringBootApplication
public class Application {

public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}

}



                                        

Step 6: Local Setup and Run the application

Step 1: Download or clone the source code from GitHub to a local machine - Click here


Step 2: mvn clean install


Step 3: Run the Spring Boot application - 

mvn spring-boot:run




Step 7: Test the APIs using postman

1. Add User:



2. Get User By Id:



3. Update User:



4. Get All Users:



5. Delete User:

Popular posts from this blog

Learn Java 8 streams with an example - print odd/even numbers from Array and List

Java Stream API - How to convert List of objects to another List of objects using Java streams?

Registration and Login with Spring Boot + Spring Security + Thymeleaf

Java, Spring Boot Mini Project - Library Management System - Download

ReactJS, Spring Boot JWT Authentication Example

Top 5 Java ORM tools - 2024

Java - Blowfish Encryption and decryption Example

Spring boot video streaming example-HTML5

Google Cloud Storage + Spring Boot - File Upload, Download, and Delete