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.
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.0.3.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 EmployeeReactiveController { 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 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 setting up and working with 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.