WebFlux

Spring WebFlux is the alternative to Spring MVC module. Spring WebFlux is used to create fully asynchronous and non-blocking application built on event-loop execution model. It is fully non-blocking, supports Reactive Streams back pressure, and runs on such servers as Netty, Undertow, and Servlet containers. Spring WebFlux is built on Project Reactor. Project Reactor is the implementation of Reactive Streams specification. Reactor provides two types:

  1. Mono: implements Publisher and returns 0 or 1 elements
  2. Flux: implements Publisher and returns N elements.

Spring Official Documentation provides comparison of Spring WebFlux to Spring Web MVC:

In summary, if you are building a traditional web application with synchronous communication, then Spring Web may be a good choice for you. If you are building a highly-concurrent application with non-blocking I/O, then Spring Webflux may be a better choice.

Let’s consider an example of building a web application that retrieves Organization data to users.

In a traditional Spring Web application, the controller would use blocking I/O to retrieve the Organization data from the API, and the user would have to wait until the data is retrieved before seeing the Organization information. This is suitable for small-scale applications with low-concurrency needs.

On the other hand, in a Spring Webflux application, the controller would use non-blocking I/O to retrieve the Organization data from the API, and the user can see the page load while the data is being retrieved in the background. This is suitable for large-scale applications with high-concurrency needs.

Spring Web example:

@RestController
public class OrganizationController {

    @Autowired
    private OrganizationService organizationService;

    @GetMapping("/organization")
    public String getOrganization() {
        OrganizationData organizationData = organizationService.getOrganizationData();
        return "Organization name: " + organizationData.getName();
    }
}

@Service
public class OrganizationService {

    @Autowired
    private RestTemplate restTemplate;

    public OrganizationData getOrganizationData() {
        ResponseEntity<OrganizationData> response = ...;
        return response.getBody();
    }
}

Spring Webflux example:

@RestController
public class OrganizationController {

    @Autowired
    private OrganizationService organizationService;

    @GetMapping("/organization")
    public Mono<String> getOrganization() {
        return organizationService.getOrganizationData().map(organizationData -> "Organization name " +    organizationData.getName());
    }
}

@Service
public class OrganizationService {

    @Autowired
    private WebClient webClient;

    public Mono<OrganizationData> getOrganizationData() {
        return webClient.get().uri(...);
    }
}

Maven dependencies for Spring Webflux:

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

		<dependency>
			<groupId>org.postgresql</groupId>
			<artifactId>r2dbc-postgresql</artifactId>
			<scope>runtime</scope>
		</dependency>

Working Example: https://github.com/ZbCiok/webflux-postgresql-example-01