Skip to content

Spring WebFlux (Reactive)

WebFlux framework is a newer framework over MVC.

  • It provides asynchronous thread safe API calls out of the box
  • Use WebClient instead of the deprecated RestFramework

WebFlux follows the Reactive pattern which is a functional programming pattern

Examples

API Call

Write spring boot code for calling an API using webflux synchronously

package com.example.demo;

import org.springframework.web.reactive.function.client.WebClient;
import org.springframework.web.reactive.function.client.WebClient.ResponseSpec;

public class WebFluxClient {

    public static void main(String[] args) {

        WebClient webClient = WebClient.create("http://localhost:8080/api/v1");

        ResponseSpec responseSpec = webClient.get().uri("/data").exchange();

        responseSpec.bodyToMono(String.class).subscribe(System.out::println);
    }
}

Rest Controller

A simple rest controller with WebFlux

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

import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/users")
public class MyRestController {

    private final UserRepository userRepository;

    private final CustomerRepository customerRepository;

    public MyRestController(UserRepository userRepository, CustomerRepository customerRepository) {
        this.userRepository = userRepository;
        this.customerRepository = customerRepository;
    }

    @GetMapping("/{userId}")
    public Mono<User> getUser(@PathVariable Long userId) {
        return this.userRepository.findById(userId);
    }

    @GetMapping("/{userId}/customers")
    public Flux<Customer> getUserCustomers(@PathVariable Long userId) {
        return this.userRepository.findById(userId).flatMapMany(this.customerRepository::findByUser);
    }

    @DeleteMapping("/{userId}")
    public Mono<Void> deleteUser(@PathVariable Long userId) {
        return this.userRepository.deleteById(userId);
    }

}
  • Mono = 0 to 1 value
  • Flux = 0 to N values

https://reflectoring.io/reactive-architecture-with-spring-boot/

Resources