top of page

Introduction to Spring WebFlux



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

0 comments
bottom of page