Notes of Spring Reactive

1 minute read

Reactive programming

Spring WebFlux

Passing context between steps in the pipeline

Reactive Spring Data

Handling errors

        return Mono
                .just(
                        repository.findById(id)
                )
                .switchIfEmpty(Mono.error(new HttpClientErrorException(HttpStatus.BAD_REQUEST, "")))
                .flatMap(entity -> repository.updateById(id, entity))
                .map(createdEntity -> conversionService.convert(createdEntity, TargetObject.class));
        // @formatter:on
  • common method to return error while empty. link
public <T> Mono<T> errorIfEmpty(Mono<T> source) {
  return source.switchIfEmpty(Mono.defer(() -> Mono.error(new RuntimeException())));
}

Mono<String> foo = Mono.empty().transform(this::errorIfEmpty);

Spring Reactive WebClient

Create WebClient with custom connect/read [[timeout]]

If it’s just to avoid the timeout during debug, the timeout can be configured at the webclient level.

        // @formatter:off
        webClient = WebTestClient.bindToServer()
                .baseUrl(buildServerApiUrl())
                .defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
                .responseTimeout(Duration.ofMillis(60000)) // this sets the timeout to 60s
                .build();
        // @formatter:on
private WebClient createWebClientWithConnectAndReadTimeOuts(int connectTimeOut, long readTimeOut) {
        // create reactor netty HTTP client
        HttpClient httpClient = HttpClient.create()
                .tcpConfiguration(tcpClient -> {
                    tcpClient = tcpClient.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, connectTimeOut);
                    tcpClient = tcpClient.doOnConnected(conn -> conn
                            .addHandlerLast(new ReadTimeoutHandler(readTimeOut, TimeUnit.MILLISECONDS)));
                    return tcpClient;
                });
        // create a client http connector using above http client
        ClientHttpConnector connector = new ReactorClientHttpConnector(httpClient);
        // use this configured http connector to build the web client
        return WebClient.builder().clientConnector(connector).build();
    }

Sample projects

Updated:

Comments