Spring WebFlux provides reactive, async, non-blocking programming support for web applications in an annotated Controller format similar to SpringMVC.
This approach is similar to how Node.js uses an async, non-blocking model which helps make it more scalable. Spring WebFlux uses a similar model but with multiple event loops.
Spring WebFlux moves away from the thread-per-request blocking model in traditional SpringMVC(with Tomcat by default) and moves towards a multi-EventLoop, async, non-blocking(with Netty by default) paradigm with back-pressure that is more scalable and efficient than traditional blocking code. For a more general introduction to Reactive Functional Programing with Java check out: https://medium.com/javarevisited/intro-to-reactive-functional-programming-d49e00365847 Interested in a full course on Reactive Spring? Check out these courses on LinkedIn Learning:
Reactive Spring
Building a Reactive App with Angular and SpringBoot 2
Spring Reactive Stack
Spring Reactive Stack
The Spring Reactive Stack consists of:
Spring Boot 2+
Project Reactor
Spring WebFlux
Netty(as the default web server instead of Tomcat)
Spring Data Reactive Repositories
Why Use Spring WebFlux?
Spring WebFlux will allow you to more efficiently leverage CPU and network resources, provide a more scalable architecture and a more responsive user experience.
From the Spring WebFlux Docs
Why was Spring WebFlux created?
Part of the answer is the need for a non-blocking web stack to handle concurrency with a small number of threads and scale with fewer hardware resources. … That is important because of servers such as Netty that are well-established in the async, non-blocking space. … The other part of the answer is functional programming. The addition of lambda expressions in Java 8 created opportunities for functional APIs in Java. This is a boon for non-blocking applications and continuation-style APIs that allow declarative composition of asynchronous logic.
Spring WebFlux Framework
Spring WebFlux is built on Project Reactor which implements the Reactive Streams specification.
From the Reactive Streams docs:
Reactive Streams is an initiative to provide a standard for asynchronous stream processing with non-blocking back pressure.
This encompasses efforts aimed at runtime environments (JVM and JavaScript) as well as network protocols.
WebFlux provides support for two paradigms:
Annotation-based Spring Controllers(Similar to SpringMVC)
Functional Endpoints that allow for functional, fluent API style routing and handler functions
Spring WebFlux in Action
Spring WebFlux in Action
Spring Boot Starters
Spring Boot exposes a Spring Boot starter for Spring WebFlux reactive web apps: spring-boot-starter-webflux
Maven:
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-webflux -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
Gradle:
//https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-webflux
compile('org.springframework.boot:spring-boot-starter-webflux')
You may also want to consider bringing in this dependency for your test classes: io.projectreactor:reactor-test
When bootstrapping an application from Spring Initializr be sure to select Spring Reactive Web as a dependency.
Spring Initialzr with Spring Web FLux
You will also want to leverage a Spring Data Reactive dependency to get the full benefit of a reactive, async, non-blocking architecture.
Examples of Spring Data Reactive Libraries:
Spring Data Reactive for Apache Cassandra
Spring Data Reactive MongoDB
Spring Data Reactive Redis
Annotated Spring WebFlux RestController
Here is an example of an annotated Spring WebFlux Controller:
Spring WebFlux Controller Example
@RestController
@RequestMapping("api/v1/room/reservation/")
public class ReservationResource {
@GetMapping(path = "/{roomId}")
public Mono<Reservation> getReservationById(@PathVariable Mono<String> roomId) {
return //Call your service layer here
}
}
As you can see this code is very similar to Spring MVC with the exception of the return type being a Reactive Publisher, in this case a Mono that emits a Reservation object(A DTO from this sample project). Mono: a Reactive Publisher that emits 1 or zero elements than terminates.
In other words, a Mono is like an async, promise or a future that will emit an element.
From the Spring JavaDocs for the Mono type:
A Reactive Streams Publisher with basic rx operators that emits at most one item via the onNext signal then terminates with an onComplete signal (successful Mono, with or without value), or only emits a single onError signal (failed Mono).
Mono in Action
Spring Reactive Publisher Mono in Action
Using a Spring Data Reactive Repository
Now that you have a Reactive Controller, you will then want to hook into a Service layer that leverages a Spring Data Reactive Repository.
Spring Reactive Repository Example
public interface ReactiveReservationRepository
extends ReactiveCrudRepository<Reservation, String> {
Mono<Reservation> findById(Mono<String> roomId);
}
Calling a Reactive Repository from a WebFlux Controller
@RestController
@RequestMapping("api/v1/room/reservation/")
public class ReservationResource {
...
@GetMapping(path = "/{roomId}")
public Mono<Reservation> getReservationById(@PathVariable Mono<String> roomId) {
// It is implied this @Bean is @Autowired into this class
return reactiveReservationRepository.findById(roomId);
}
...
}
If you use a service layer, be sure to make the return type of your service methods a Reactive Publisher like Mono or Flux.
Source: Medium
The Tech Platform
Comments