Salient Features of Spring WebFlux

Reading Time: 4 minutes

What is Spring WebFlux?

Spring WebFlux is a fully non-blocking, annotation-based web framework built on Project Reactor that makes it possible to build reactive applications on the HTTP layer. WebFlux uses a new router functions feature to apply functional programming to the web layer and bypass declarative controllers and RequestMappings. It requires you to import Reactor as a core dependency.

WebFlux was added in Spring 5 as a reactive alternative to Spring MVC, with added support for:

  • Non-blocking threads: Concurrent threads that complete their designated task without waiting for previous tasks must complete.
  • Reactive Stream API: A standardized tool that includes options for asynchronous stream processing with non-blocking backpressure.
  • Asynchronous data processing: When data is purified in the background and the user can continue using normal app functionality without interruption.

Ultimately, WebFlux does away with SpringMVCs thread-per-request model and instead uses a multi-EventLoop non-blocking model to enable reactive, scalable apps. With support for popular servers like Netty, Undertow, and Servlet 3.1+ containers, WebFlux has come in as a key part of a reactive stack.

Salient Features of Spring WebFlux

Router functions

RouterFunction is a functional alternative to the @RequestMapping and @Controller annotation style used in standard Spring MVC.

We can use it to route requests to the handler functions:

Traditional

@RestController 

public class ProductController { 

@RequestMapping("/product") 

public List<Product> productListing() {
 
return ps.findAll(); 

} 
}

Functional

@Bean

public RouterFunction<ServerResponse> productListing(ProductService ps) {

    return route().GET("/product", req -> ok().body(ps.findAll()))
      .build();

}

Router functions avoid potential side effects caused by the multi-step process of request mapping and instead streamline it to a direct router/handler chain. This allows for functional programming implementations of reactive programming.

RequestMapping and Controller annotation styles are still valid in WebFlux if you are more comfortable with the old style, RouterFunctions is just a new option for your solutions.

WebClient

WebClient is WebFlux’s reactive web client built from the well-known RestTemplate. It is an interface that represents the main entry point for web requests and supports both synchronous and asynchronous operations. It mostly operates for reactive backend-to-backend communication.

You can build and create a WebClient instance by importing standard WebFlux dependencies with Maven:

<dependency>

    <groupId>org.springframework.boot</groupId>

    <artifactId>spring-boot-starter-webflux</artifactId>

</dependency>
WebClient client = WebClient.create();

Reactive Steam API

Reactive Stream API is an imported collection of functions that allow for smarter stream data flow. It has built-in support for back-pressure and asynchronous processing that ensures the application makes the most efficient use of both computer and component resources.

There are four main interfaces in Reactive Stream API:

  • Publisher: Emits events to be linked Subscribers based on their demands. Acts as a central linking point that subscribers can watch for events.
  • Subscriber: Receives and processes events emitted by Publisher. Multiple Subscribers can link to a single Publisher and respond differently to the same event. Subscribers may set to react:
    • onNext, when it receives the next event.
    • onSubscribe, when a new subscriber is added
    • onError, when an error occurs with another subscriber
    • onComplete, when another subscriber finishes its task
  • Subscription: Defines a relationship between selected Publisher and Subscriber. Each Subscriber can only be linked to a single Publisher.
  • Processor: Represents the processing stage of the Subscriber

Servers

WebFlux is holding on Tomcat, Jetty, and Servlet 3.1+ containers, as well as on non-Servlet runtimes such as Netty and Undertow. Netty is most commonly utilized for async and non-blocking designs, so WebFlux will default to that. You can easily switch between these server options with a simple change to your Maven or Gradle build software.

This makes WebFlux highly versatile in what technologies it can work with and allows you to easily implement it with existing infrastructure.

Concurrency Model

WebFlux is built with non-blocking in mind and therefore uses a different concurrent programming model from Spring MVC.

Spring MVC assumes threads will block and uses a large thread pool to keep moving during instances of blocking. This larger thread pool makes MVC more resource-intensive as the computer hardware must keep more threads spun up at once.

WebFlux instead uses a small thread pool because it assumes you’ll never need to pass off work to avoid a blocker. These threads, called event loop workers, are fixed in number and cycle through incoming requests quicker than MVC threads. This means WebFlux uses computer resources more efficiently because active threads are always working.

Spring WebFlux Security

WebFlux uses Spring Security to implement authentication and authorization protocols. Spring Security uses WebFilter to check requests against an authenticated list of users, or it can be set to automatically refuse requests that fit criteria like origin or request type.

@EnableWebFluxSecurity

public class HelloWebFluxSecurityConfig {

    @Bean
    public MapReactiveUserDetailsService userDetailsService() {

        UserDetails user = User.withDefaultPasswordEncoder()

            .username("user")

            .password("user")

            .roles("USER")

            .build();

        return new MapReactiveUserDetailsService(user);

    }
}

Since this is a minimal implementation that sets all settings to default. So, here we can see that the user has a username, a password, and one or more roles tags that allow them a certain level of access.

Keep learning WebFlux.

Learn to create RESTful, reactive web services in half the time. Educative hands-on courses with live coding environments let them spend less time setting up and more time practicing.

Get Started with Spring WebFlux

Now let’s get hands-on with WebFlux. Firstly, we’ll need to set up a project. We’ll use Spring Initializr it to generate a Maven build with the Spring Reactive Web dependency.

This will generate a pom.xml file that looks like this:

<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.o

rg/2001/XMLSchema-instance"

    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apach

e.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.4.2</version>

        <relativePath/> <!-- lookup parent from repository -->

    </parent>

    <groupId>com.example</groupId>

    <artifactId>reactive-rest-service</artifactId>

    <version>0.0.1-SNAPSHOT</version>

    <name>reactive-rest-service</name>

    <description>Demo project for Spring Boot</description>
    
   <properties>

        <java.version>11</java.version>
 
   </properties>

    <dependencies>

        <dependency>

            <groupId>org.springframework.boot</groupId>

            <artifactId>spring-boot-starter-webflux</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>

    <build>

        <plugins>

            <plugin>

                <groupId>org.springframework.boot</groupId>

                <artifactId>spring-boot-maven-plugin</artifactId>

            </plugin>

        </plugins>

    </build>

</project>

Therefore, now we have everything you need to continue! From here we’ll add some components to make an Hello-World app. We’ll just add a router and a handler, which are the minimum requirements to create our basic WebFlux app.

Router

Firstly, we’ll create an example router to show our text once at the URL http://localhost:8080/example. This defines how the user can request the data that we’ll define in our handler.

@Configuration

public class ExampleRouter {

  @Bean
  public RouterFunction<ServerResponse> routeExample 

  (ExampleHandler exampleHandler) {

    return RouterFunctions

        .route(RequestPredicates.GET("/example").and(RequestPredicates

        .accept(MediaType.TEXT_PLAIN)), exampleHandler::hello);

  }
}

Handler

Secondly, we’ll add a handler that listens to any user requesting the /example route. Once the router recognizes that the requested path matches It sends the user to the handler. Our handler receives the message and brings the user to a page with our greeting.

@Component

public class ExampleHandler {

  public Mono<ServerResponse> hello(ServerRequest request) {

    return ServerResponse.ok().contentType(MediaType.TEXT_PLAIN)

         .body(BodyInserters.fromObject("Hello, Spring WebFlux Example!"));

  }
}

Run the application

Now we’ll run our application by executing the Maven target spring-boot:run. You’ll now be able to visit http://localhost:8080/example in your browser to find similarly:

Hello, Spring WebFlux Example!

Written by 

He is a Software Consultant at Knoldus Inc. He has done B.Tech from Dr. APJ Kalam Technical University Uttar-Pradesh. He is passionate about his work and having the knowledge of various programming languages like Java, C++, Python. But he is passionate about Java development and curious to learn Java Technologies. He is always impatient and enthusiastic to learn new things. He is good skills of Critical thinking and problem solving and always enjoy to help others. He likes to play outdoor games like Football, Volleyball, Hockey and Kabaddi. Apart from the technology he likes to read scriptures originating in ancient India like Veda,Upanishad,Geeta etc.