Guide to Spring 5 WebFlux

1. Overview

Spring WebFlux framework is part of Spring 5 and provides reactive programming support for web applications.

In this tutorial, we’ll be creating a small reactive REST application using the reactive web components RestController and WebClient.

We will also be looking at how to secure our reactive endpoints using Spring Security.

Further reading:

Spring 5 WebClient

Discover Spring 5’s WebClient – a new reactive RestTemplate alternative.

Read more

Spring WebClient vs. RestTemplate

Learn how to make server-side HTTP calls using WebClient and RestTemplate.

Read more

2. Spring WebFlux Framework

Spring WebFlux internally uses Project Reactor and its publisher implementations – Flux and Mono.

The new framework supports two programming models:

  • Annotation-based reactive components

  • Functional routing and handling

Here, we’re going to be focusing on the Annotation-based reactive components, as we already explored the functional style – routing and handling.

3. Dependencies

Let’s start with the spring-boot-starter-webflux dependency, which actually pulls in all other required dependencies:

  • spring-boot and spring-boot-starter for basic Spring Boot application setup

  • spring-webflux framework

  • reactor-core that we need for reactive streams and also reactor-netty

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-webflux</artifactId>
    <version>2.1.6.RELEASE</version>
</dependency>

The latest spring-boot-starter-webflux can be downloaded from Maven Central.

4. Reactive REST Application

We’ll now build a very simple Reactive REST EmployeeManagement application – using Spring WebFlux:

  • We’ll use a simple domain model – Employee with an id and a name field

  • We’ll build REST APIs for publishing and retrieve Single as well as Collection Employee resources using RestController and WebClient

  • And we will also be creating a secured reactive endpoint using WebFlux and Spring Security

5. Reactive RestController

Spring WebFlux supports the annotation-based configurations in the same way as Spring Web MVC framework.

To begin with, on the server side, we create an annotated controller that publishes our reactive streams of Employee.

Let’s create our annotated EmployeeController:

@RestController
@RequestMapping("/employees")
public class EmployeeController {

    private final EmployeeRepository employeeRepository;

    // constructor...
}

EmployeeRepository can be any data repository that supports non-blocking reactive streams.

5.1. Single Resource

Let’s create an endpoint in our controller that publishes a single Employee resource:

@GetMapping("/{id}")
private Mono<Employee> getEmployeeById(@PathVariable String id) {
    return employeeRepository.findEmployeeById(id);
}

For a single Employee resource, we have used a Mono of type Employee because it will emit at most 1 element.

5.2. Collection Resource

Let’s also add an endpoint in our controller that publishes the collection resource of all Employees:

@GetMapping
private Flux<Employee> getAllEmployees() {
    return employeeRepository.findAllEmployees();
}

For the collection resource, we have used Flux of type Employee – since that’s the publisher focused on emitting 0..n elements.

6. Reactive Web Client

WebClient introduced in Spring 5 is a non-blocking client with support for Reactive Streams.

On the client side, we use WebClient to retrieve data from our endpoints created in EmployeeController.

Let’s create a simple EmployeeWebClient:

public class EmployeeWebClient {

    WebClient client = WebClient.create("http://localhost:8080");

    // ...
}

Here we have created a WebClient using its factory method create. It’ll point to localhost:8080 for relative URLs.

6.1. Retrieving a Single Resource

To retrieve single resource of type Mono from endpoint /employee/{id}:

Mono<Employee> employeeMono = client.get()
  .uri("/employees/{id}", "1")
  .retrieve()
  .bodyToMono(Employee.class);

employeeMono.subscribe(System.out::println);

6.2. Retrieving Collection Resource

Similarly, to retrieve a collection resource of type Flux from endpoint /employees:

Flux<Employee> employeeFlux = client.get()
  .uri("/employees")
  .retrieve()
  .bodyToFlux(Employee.class);

employeeFlux.subscribe(System.out::println);

We also have a detailed article on link:/spring-5-webclient.

7. Spring WebFlux Security

We can use Spring Security to secure our reactive endpoints.

Let’s suppose we have a new endpoint in our EmployeeController. This endpoint updates Employee details and sends back the updated Employee.

Since this allows users to change existing employees, we want to restrict this endpoint to ADMIN role users only.

Let’s add a new method to our EmployeeController:

@PostMapping("/update")
private Mono<Employee> updateEmployee(@RequestBody Employee employee) {
    return employeeRepository.updateEmployee(employee);
}

Now, to restrict access to this method let’s create SecurityConfig and define some path-based rules to only allow ADMIN users:

@EnableWebFluxSecurity
public class EmployeeWebSecurityConfig {

    // ...

    @Bean
    public SecurityWebFilterChain springSecurityFilterChain(
      ServerHttpSecurity http) {
        http.csrf().disable()
          .authorizeExchange()
          .pathMatchers(HttpMethod.POST, "/employees/update").hasRole("ADMIN")
          .pathMatchers("/**").permitAll()
          .and()
          .httpBasic();
        return http.build();
    }
}

This configuration will restrict access to the endpoint /employees/update. Therefore only users having a role ADMIN will be able to access this endpoint and update an existing Employee.

Finally, the annotation @EnableWebFluxSecurity adds Spring Security WebFlux support with some default configurations.

We also have a detailed article on configuring and working with Spring WebFlux security.

8. Conclusion

In this article, we’ve explored how to create and work with reactive web components supported by Spring WebFlux framework by creating a small Reactive REST application.

We learned how to use RestController and WebClient to publish and consume reactive streams respectively.

We also looked into how to create a secured reactive endpoint with the help of Spring Security.

Other than Reactive RestController and WebClient, WebFlux framework also supports reactive WebSocket and corresponding WebSocketClient for socket style streaming of Reactive Streams.

We have a detailed article focused on working with Reactive WebSocket with Spring 5.

Finally, the complete source code used in this tutorial is available over on Github.

Leave a Reply

Your email address will not be published.