Enterprise Java

Reactive Microservices with Spring WebFlux

Building Fully Non-Blocking REST APIs with Reactor and WebFlux

Modern applications are under constant pressure to serve thousands of concurrent requests while remaining fast and responsive. Traditional servlet-based stacks like Spring MVC, while reliable, are fundamentally synchronous and thread-blocking. As systems scale, this model can become a bottleneck.

Spring WebFlux provides a reactive, non-blocking foundation for building high-throughput microservices that scale gracefully under load. In this article, you’ll learn what makes WebFlux different, why you should consider it, and how to build a reactive REST API step by step.

Spring WebFlux and Reactor

1. What is Spring WebFlux?

Spring WebFlux is a reactive web framework introduced in Spring 5. It supports building applications on:

  • Reactive Streams: A specification for asynchronous data processing with backpressure.
  • Project Reactor: A reactive library providing Mono and Flux types.
  • Non-blocking runtimes: Netty (default), Undertow, or servlet containers in asynchronous mode.

With WebFlux, you no longer block a thread per request. Instead, you declare reactive pipelines that process data asynchronously, letting the runtime handle efficient scheduling.

2. Why Go Reactive?

Traditional Spring MVC is perfectly fine for many use cases, but if you need:

✅ High concurrency (thousands of requests)
✅ Streaming data over HTTP
✅ Backpressure handling
✅ Better resource utilization under load

… then WebFlux shines. For example, a small pool of threads can handle many I/O-bound operations concurrently because threads aren’t blocked waiting for responses.

3. Core Concepts

Mono and Flux

At the heart of WebFlux is Project Reactor:

  • Mono<T> – 0..1 values (e.g., a single result or empty)
  • Flux<T> – 0..N values (e.g., a stream)

Think of them as reactive equivalents to Optional and List, but asynchronous.

Backpressure

Backpressure allows the consumer to control the rate of data emission, preventing overload.

4. Creating a Reactive REST API

Let’s build a simple microservice exposing a reactive REST API.

1️⃣ Setup Your Project

In Maven, include:

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<dependency>
  <groupId>io.projectreactor</groupId>
  <artifactId>reactor-core</artifactId>
</dependency>

Spring Boot will auto-configure a Netty-based reactive server.

2️⃣ Define a Reactive Repository

You can integrate with reactive data stores (like MongoDB). For simplicity, here’s an in-memory example:

import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

public interface PersonRepository {
    Flux<Person> findAll();
    Mono<Person> findById(String id);
    Mono<Person> save(Person person);
}

A simple implementation:

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

public class InMemoryPersonRepository implements PersonRepository {
    private final Map<String, Person> store = new ConcurrentHashMap<>();

    @Override
    public Flux<Person> findAll() {
        return Flux.fromIterable(store.values());
    }

    @Override
    public Mono<Person> findById(String id) {
        return Mono.justOrEmpty(store.get(id));
    }

    @Override
    public Mono<Person> save(Person person) {
        store.put(person.id(), person);
        return Mono.just(person);
    }
}

3️⃣ Define a Reactive Controller

import org.springframework.web.bind.annotation.*;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

@RestController
@RequestMapping("/api/people")
public class PersonController {

    private final PersonRepository repository;

    public PersonController(PersonRepository repository) {
        this.repository = repository;
    }

    @GetMapping
    public Flux<Person> getAll() {
        return repository.findAll();
    }

    @GetMapping("/{id}")
    public Mono<Person> getById(@PathVariable String id) {
        return repository.findById(id);
    }

    @PostMapping
    public Mono<Person> create(@RequestBody Person person) {
        return repository.save(person);
    }
}

4️⃣ Streaming Data

Reactive APIs are great for server-sent events:

@GetMapping(value = "/stream", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public Flux<Person> streamPeople() {
    return repository.findAll()
            .delayElements(Duration.ofSeconds(1)); // Simulate streaming
}

Calling /api/people/stream will emit one person per second.

5. Testing the API

Use curl:

curl http://localhost:8080/api/people

Or test streaming:

curl http://localhost:8080/api/people/stream

6. Synchronous vs. Reactive: A Quick Comparison

AspectSpring MVCSpring WebFlux
Programming ModelServlet (synchronous)Reactive Streams (async)
Thread ModelOne thread per requestEvent loop (non-blocking)
BackpressureNoYes
Data typesList, OptionalFlux, Mono
ScalabilityLimited by thread pool sizeHigh concurrency

7. Best Practices and Opinions

Start Reactive Only if Needed
Not all workloads benefit. Use it primarily for I/O-bound, high-concurrency cases.

Avoid Mixing Blocking Calls
Never call blocking APIs inside reactive pipelines (.block(), JDBC). This negates the benefits.

Leverage Reactive Databases
Use reactive drivers (R2DBC, Mongo Reactive) to keep the stack non-blocking end to end.

Think in Streams
Model flows as sequences and transformations, not imperative steps.

Test with StepVerifier
Use Reactor’s StepVerifier to write clear, deterministic tests.

8. Conclusion

Spring WebFlux empowers you to build modern, scalable microservices that thrive under heavy load. By embracing the reactive paradigm with Project Reactor, you can handle streaming data, maintain backpressure, and achieve higher throughput with fewer resources.

While reactive programming has a learning curve, it’s a powerful tool in your Spring Boot toolkit—and one that pays off when you need responsiveness and scalability.

Further Reading

Eleftheria Drosopoulou

Eleftheria is an Experienced Business Analyst with a robust background in the computer software industry. Proficient in Computer Software Training, Digital Marketing, HTML Scripting, and Microsoft Office, they bring a wealth of technical skills to the table. Additionally, she has a love for writing articles on various tech subjects, showcasing a talent for translating complex concepts into accessible content.
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Oldest
Newest Most Voted
Back to top button