Spring WebFlux
The reactive web stack: controllers that return Mono/Flux and handle massive concurrency on few threads.
On this page
You've built BookVault on Spring MVC - the blocking, servlet-based web stack. Spring
offers a parallel, fully non-blocking web stack: Spring WebFlux. Same annotations you
already know, but controllers return Mono and Flux, and the whole request runs without
ever blocking a thread.
Familiar, but reactive
A WebFlux controller looks almost identical to an MVC one - the return types change:
@RestController
@RequestMapping("/api/books")
class BookController {
@GetMapping("/{isbn}")
Mono<Book> byIsbn(@PathVariable String isbn) { // a single async value
return repository.findByIsbn(isbn);
}
@GetMapping
Flux<Book> all() { // a stream of values
return repository.findAll();
}
}You don't call .subscribe() - the framework subscribes when the HTTP response is
written, streaming each value to the client as it arrives.
Driving an electric car feels almost exactly like a petrol one - same wheel, pedals, and road signs - but the engine underneath is completely different. WebFlux is the electric engine of the Spring web world: the annotations and mental model you learned in MVC still apply, while underneath it runs on a non-blocking event loop instead of a thread per request.
MVC or WebFlux?
| Choose… | When |
|---|---|
| Spring MVC | Standard apps, blocking JDBC/JPA, a team that knows it - the safe default |
| Spring WebFlux | Very high concurrency, streaming, or an already fully-reactive stack |
They don't mix within one request: going reactive means the whole chain - web, service, and database - must be non-blocking, or you lose the benefit (and can deadlock the event loop with a stray blocking call).
Reactive is all-or-nothing per request
A WebFlux controller that calls blocking JPA gets the worst of both worlds: it blocks the precious event-loop threads. To be reactive end to end you need reactive data access too - which is the next lesson, R2DBC.
BookVault is a standard CRUD API backed by JPA/PostgreSQL, serving a moderate number of users. A colleague suggests rewriting it in WebFlux "for performance." Explain whether that would actually help, and what would have to change for reactive to pay off.
What is required for a Spring WebFlux request to actually be non-blocking end to end?
Key takeaways
- Spring WebFlux is a fully non-blocking web stack parallel to Spring MVC, using the same annotations.
- Controllers return Mono/Flux and the framework subscribes when writing the response - streaming values as they arrive.
- Choose MVC for standard blocking apps (the default); choose WebFlux for very high concurrency or streaming.
- Reactive is all-or-nothing per request: web, service, and data must all be non-blocking, or you lose the benefit.
- WebFlux improves concurrency under load, not single-request latency.