Spring WebFlux enables reactive programming in Spring. Here’s when and how to use it.

When to Use WebFlux

Use WebFlux When:

  • High concurrency requirements
  • Non-blocking I/O needed
  • Streaming data
  • Microservices with reactive backends

Use MVC When:

  • Traditional request-response
  • Blocking operations
  • Existing Spring MVC codebase
  • Simpler mental model needed

Basic Setup

Dependencies

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

Reactive Controller

@RestController
public class UserController {
    
    @GetMapping("/users")
    public Flux<User> getUsers() {
        return userService.findAll();
    }
    
    @GetMapping("/users/{id}")
    public Mono<User> getUser(@PathVariable Long id) {
        return userService.findById(id);
    }
    
    @PostMapping("/users")
    public Mono<User> createUser(@RequestBody Mono<User> user) {
        return userService.save(user);
    }
}

Reactive Types

Mono

// Single value or empty
Mono<String> mono = Mono.just("Hello");
Mono<String> empty = Mono.empty();
Mono<String> error = Mono.error(new RuntimeException());

Flux

// Multiple values
Flux<String> flux = Flux.just("A", "B", "C");
Flux<Integer> range = Flux.range(1, 10);

Reactive Repository

public interface UserRepository extends ReactiveCrudRepository<User, Long> {
    Flux<User> findByStatus(String status);
    Mono<User> findByEmail(String email);
}

Error Handling

@GetMapping("/users/{id}")
public Mono<User> getUser(@PathVariable Long id) {
    return userService.findById(id)
        .switchIfEmpty(Mono.error(new UserNotFoundException()))
        .onErrorResume(error -> {
            // Handle error
            return Mono.empty();
        });
}

Testing

@SpringBootTest
@AutoConfigureWebTestClient
class UserControllerTest {
    
    @Autowired
    private WebTestClient webTestClient;
    
    @Test
    void shouldGetUsers() {
        webTestClient.get()
            .uri("/users")
            .exchange()
            .expectStatus().isOk()
            .expectBodyList(User.class);
    }
}

Best Practices

  1. Use reactive types throughout
  2. Avoid blocking operations
  3. Handle errors properly
  4. Use backpressure
  5. Monitor performance

Conclusion

Spring WebFlux provides:

  • Non-blocking I/O
  • High concurrency
  • Reactive streams
  • Better resource utilization

Use WebFlux for reactive applications! ⚡