Basic Introduction to 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 (with Tomcat by default) and moves towards a multi-EventLoop, async, non-blocking(with 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: http://jeetwincasinos.com/javarevisited/intro-to-reactive-functional-programming-d49e00365847
Interested in a full course on Reactive Spring? Check out this course on LinkedIn Learning:
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 which implements the 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 Boot Starters
Spring Boot exposes a Spring Boot starter for Spring WebFlux reactive web apps:
Maven:
<!-- -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
Gradle:
//
compile('org.springframework.boot:spring-boot-starter-webflux')
You may also want to consider bringing in this dependency for your test classes:
When bootstrapping an application from be sure to select Spring Reactive Web as a dependency.
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
}
}
View the source code for this Controller in the context of a
As you can see this code is very similar to with the exception of the return type being a Reactive Publisher, in this case a that emits a Reservation object(A DTO from this ).
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
with basic rx operators that emits at most one item via the
onNext
signal then terminates with anonComplete
signal (successful Mono, with or without value), or only emits a singleonError
signal (failed Mono).
Mono in Action
Subscribers to the Mono will receive a single emitted element(Or an error signal) and then a completion signal.
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);
}
Checkout this article for more details on how to configure Spring Reactive Data:
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.
Sample Project
Check out this Github repo for a full example of a Reactive Application.
Interested in a full course on Reactive Spring? Check out this course on LinkedIn Learning:
Check out my website for all my platforms and videos: