Starter for building WebFlux applications using Spring Framework's Reactive Web support
npx @tessl/cli install tessl/maven-org-springframework-boot--spring-boot-starter-webflux@3.5.0Spring Boot WebFlux Starter provides a comprehensive foundation for building reactive, non-blocking web applications using Spring Framework's reactive web support. It automatically configures Spring WebFlux with Reactor Netty, includes reactive JSON processing, and integrates seamlessly with the reactive ecosystem for building scalable microservices and real-time applications.
pom.xml dependencies:<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
<version>3.5.3</version>
</dependency>For Gradle:
implementation 'org.springframework.boot:spring-boot-starter-webflux:3.5.3'Spring Boot WebFlux provides two programming models through standard Spring imports:
// Annotation-based controllers
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.PathVariable;
// Reactive types
import reactor.core.publisher.Mono;
import reactor.core.publisher.Flux;
// Functional routing
import org.springframework.web.reactive.function.server.RouterFunction;
import org.springframework.web.reactive.function.server.RouterFunctions;
import org.springframework.web.reactive.function.server.ServerRequest;
import org.springframework.web.reactive.function.server.ServerResponse;
// WebClient for reactive HTTP calls
import org.springframework.web.reactive.function.client.WebClient;@RestController
@RequestMapping("/api/users")
public class UserController {
@GetMapping("/{id}")
public Mono<User> getUser(@PathVariable String id) {
return userService.findById(id);
}
@GetMapping
public Flux<User> getAllUsers() {
return userService.findAll();
}
@PostMapping
public Mono<User> createUser(@RequestBody Mono<User> user) {
return user.flatMap(userService::save);
}
}@Configuration
public class RouterConfiguration {
@Bean
public RouterFunction<ServerResponse> apiRoutes(UserHandler handler) {
return RouterFunctions.route()
.GET("/api/users/{id}", handler::getUser)
.GET("/api/users", handler::listUsers)
.POST("/api/users", handler::createUser)
.build();
}
}@Service
public class ExternalApiService {
private final WebClient webClient;
public ExternalApiService(WebClient.Builder builder) {
this.webClient = builder.baseUrl("https://api.example.com").build();
}
public Mono<ApiResponse> fetchData(String id) {
return webClient.get()
.uri("/data/{id}", id)
.retrieve()
.bodyToMono(ApiResponse.class);
}
}Spring Boot WebFlux Starter brings together several key components:
Traditional Spring MVC-style controllers enhanced with reactive return types. Perfect for developers familiar with Spring MVC who want to adopt reactive programming.
@RestController
public class ReactiveController {
@GetMapping("/resource/{id}")
public Mono<Resource> getResource(@PathVariable String id) { }
@PostMapping("/resource")
public Mono<Resource> createResource(@RequestBody Mono<Resource> resource) { }
}Modern functional approach using router functions and handler functions. Ideal for building lightweight, composable APIs with explicit request routing.
public interface RouterFunction<T extends ServerResponse> {
Mono<HandlerFunction<T>> route(ServerRequest request);
}
public class RouterFunctions {
public static <T extends ServerResponse> RouterFunction<T> route(
RequestPredicate predicate,
HandlerFunction<T> handlerFunction
) { }
}WebClient provides a modern, reactive HTTP client for making non-blocking HTTP requests with full integration into the reactive ecosystem.
public interface WebClient {
RequestHeadersUriSpec<?> get();
RequestBodyUriSpec post();
RequestBodyUriSpec put();
RequestHeadersUriSpec<?> delete();
interface Builder {
Builder baseUrl(String baseUrl);
Builder defaultHeader(String header, String... values);
WebClient build();
}
}Comprehensive server configuration supporting multiple embedded servers with extensive customization options for production deployments.
public interface ReactiveWebServerFactory {
WebServer getWebServer(HttpHandler httpHandler);
}
public interface ConfigurableReactiveWebServerFactory extends ReactiveWebServerFactory {
void setPort(int port);
void setAddress(InetAddress address);
void setSsl(Ssl ssl);
}Reactive error handling with customizable exception handlers, providing consistent error responses across different content types.
public interface ErrorWebExceptionHandler extends WebExceptionHandler {
Mono<Void> handle(ServerWebExchange exchange, Throwable ex);
}
public abstract class AbstractErrorWebExceptionHandler implements ErrorWebExceptionHandler {
protected abstract RouterFunction<ServerResponse> getRoutingFunction(ErrorAttributes errorAttributes);
}Comprehensive configuration options through Spring Boot properties for customizing WebFlux behavior, static resources, and server settings.
@ConfigurationProperties("spring.webflux")
public class WebFluxProperties {
private String basePath;
private String staticPathPattern = "/**";
private String webjarsPathPattern = "/webjars/**";
private boolean hiddenMethodFilter = true;
private final Format format = new Format();
private final Problemdetails problemdetails = new Problemdetails();
}Reactive testing utilities and WebTestClient for comprehensive testing of WebFlux applications with full integration testing capabilities.
public interface WebTestClient {
RequestHeadersUriSpec<?> get();
RequestBodyUriSpec post();
RequestBodyUriSpec put();
RequestBodyUriSpec patch();
RequestHeadersUriSpec<?> delete();
static Builder bindToServer();
static Builder bindToController(Object... controllers);
static Builder bindToApplicationContext(ApplicationContext applicationContext);
static Builder bindToRouterFunction(RouterFunction<?> routerFunction);
static Builder bindToWebHandler(WebHandler webHandler);
}@Repository
public interface UserRepository extends ReactiveCrudRepository<User, String> {
Flux<User> findByStatus(String status);
Mono<User> findByEmail(String email);
}@EnableWebFluxSecurity
public class SecurityConfig {
@Bean
public SecurityWebFilterChain securitygWebFilterChain(ServerHttpSecurity http) {
return http
.authorizeExchange(exchanges -> exchanges
.pathMatchers("/public/**").permitAll()
.anyExchange().authenticated()
)
.oauth2ResourceServer(ServerHttpSecurity.OAuth2ResourceServerSpec::jwt)
.build();
}
}@GetMapping(value = "/events", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public Flux<String> streamEvents() {
return Flux.interval(Duration.ofSeconds(1))
.map(sequence -> "Event " + sequence);
}