Reactive REST APIs with Spring WebFlux.fn

Daniel Marlow
OneHub | Product Engineering
2 min readMay 21, 2019

The traditional servlet-based web frameworks such as Spring MVC are blocking in nature. Spring WebFlux was introduced in Spring 5 and is a fully non-blocking, reactive framework which runs on servers such as Netty, Undertow and Servlet 3.1+ containers.

Spring WebFlux supports two programming models. Applications can be created using annotations or in a functional manner using WebFlux.fn.

Functional Endpoints

With WebFlux.fn, the programming model uses functions to route and handle requests.

  • HandlerFunction — HTTP requests are handled by a HandlerFunction which takes a ServerRequest and returns a Mono<ServerResponse>. HandlerFunctions are like the body of a @RequestMapping method in the annotation-based programming model.
  • RouterFunction — Incoming HTTP requests are routed by a RouterFunction to a Mono<HandlerFunction>. They can be considered similar to the@RequestMapping annotation.

By way of a quick overview, let’s create a simple WebFlux.fn REST API using HandlerFunction and RouterFunction.

Reactive REST APIs with WebFlux.fn

The helper function RouterFunctions.route() can be used to build routes. When a RequestPredicate is matched either the handler or an empty Mono is returned. Routes are declared as beans in a @Configuration class.

@Bean
public RouterFunction<ServerResponse> routes() {
return route(GET("/companies/{id}"), handler::getCompanyById)
.and(route(POST("/companies"), handler::updateCompany));
}

For each route the first argument defines the request that will return the corresponding handler. In this example routes have been created to a handler function that returns a Company resource by Id and to another that updates an existing Company.

In a typical application it is useful to group handler functions together. This handler class exposes a reactive CompanyRepository.

@Component
public class CompanyHandler {

private CompanyRepository companyRepository;

public CompanyHandler(CompanyRepository companyRepository) {
this.companyRepository = companyRepository;
}

public Mono<ServerResponse> getCompanyById(ServerRequest request) {
return ok().body(
companyRepository
.findById(request.pathVariable("id")), Company.class);
}
public Mono<ServerResponse> updateCompany(ServerRequest request) {
return request.bodyToMono(Company.class)
.doOnNext(companyRepository::updateCompany)
.then(ok().build());
}
}

ServerResponse provides access to the HTTP response and can be created using the build method. The builder can set the response code, response headers or a body.

Routes and handlers have now been created to get or update a Company resource in a non-blocking and reactive manner for this simple REST API.

Summary

The Spring Framework uses Reactor which is a Reactive Streams implementation to support reactive applications.

The Spring WebFlux framework was introduced in Spring 5. It has two different programming models: annotation-based and functional.

The functional model is called WebFlux.fn. RouterFunction and HandlerFunction are used to create routes to handle requests and generate responses.

--

--