How to create Reactive REST API in Spring Boot

Spring Boot Reactive Restful API with reactive streaming Examples

Purpose: In this guide, I want to show how easy it is to create a reactive REST API with Spring Boot. I would like to take a simple Use Case to show how quick it is possible to create an “active” non-blocking REST API with Spring Boot.

Case Study:In this case study we will register the employee at the company front gate and will show the registered employee in the company interview room without refreshing the page.

What is Reactive: Reactive systems have certain characteristics that make them ideal for low-latency, high-throughput workloads.

The reactor is fully non-blocking and provides efficient demand management. It directly interacts with Java's Functional API, CompletableFuture, Stream, and Duration.

What is reactive processing? Reactive processing is a paradigm that enables developers to build non-blocking, asynchronous applications that can handle back-pressure (flow control).

Why use reactive processing? Reactive systems better utilize modern processors. Also, the inclusion of back-pressure in reactive programming ensures better resilience between decoupled components.

REACTIVE CORE: Project Reactor is a fully non-blocking foundation with back-pressure support included. It’s the foundation of the reactive stack in the Spring ecosystem and is featured in projects such as Spring WebFlux, Spring Data, and Spring Cloud Gateway.

1. Setup and Create Project: Visit hereSpring Boot Rest API Hello World Examples.

Next Step. Spring Boot Parent Dependencies.


<parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.6.7</version>
        <relativePath /> <!-- lookup parent from repository -->
    </parent>
Next Step. WebFlux dependency.

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
Next Step. Spring Boot main class.

Class: Application.java

Note: @SpringBootApplication=@Configuration+ @EnableAutoConfiguration+ @ComponentScan.



package com.bce;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import com.bce.model.Employee;
import reactor.core.publisher.Sinks;

@SpringBootApplication
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
    // Reactive sink bean create here and it will return the latest object
    @Bean("empoyeePublisher")
    public Sinks.Many<Employee> sink(){
        return Sinks.many().replay().latest();
    }
}



Next Step. Create Rest Controller.


package com.bce.controller;

import java.util.concurrent.atomic.AtomicLong;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.http.codec.ServerSentEvent;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import com.bce.model.Employee;
import com.bce.service.EmployeeService;

import reactor.core.publisher.Flux;
import reactor.core.publisher.Sinks;

@RestController
public class EmployeeController {

    @Autowired
    EmployeeService employeeService;

    @Autowired
    private Sinks.Many<Employee> employeeStream;
    final AtomicLong counter = new AtomicLong();

    @PostMapping("/employee")
    public void saveEmployee(@RequestBody Employee employee) {
        employeeService.processRecords(employee);
    }

    @GetMapping(value = "/employeeStream", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
    public Flux<ServerSentEvent<Employee>> employeeStream() {
        return employeeStream.asFlux().map(e -> ServerSentEvent.builder(e).build());
    }

}

Next Step. Server Port:  The default server port is 8080. Wish you want to change open application.properties and add the below line.

server.port=8080

Next Step. Run the application and open the below URI  to view the employee http://localhost:8080/api/employeeStream. To create a employee  use this endpoint http://localhost:8080/api/employee

In the below screen we are creating employees and streaming them on a real-time basis.




Download Code from GitHub.  Download

No comments:

Post a Comment