Learn to set connection timeout, read timeout and write timeout periods for WebClient
interface available in Spring WebFlux for making synchronous and asynchronous HTTP requests.
1. Set timeouts globally via HTTPClient
We can configure the various timeouts easily at the underlying HTTP client library. It is the most easy and efficient way to configure timeout values globally for the whole application.
import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; import org.springframework.http.client.reactive.ClientHttpConnector; import org.springframework.http.client.reactive.ReactorClientHttpConnector; import org.springframework.web.reactive.config.EnableWebFlux; import org.springframework.web.reactive.config.WebFluxConfigurer; import org.springframework.web.reactive.function.client.WebClient; import io.netty.channel.ChannelOption; import io.netty.handler.timeout.ReadTimeoutHandler; import io.netty.handler.timeout.WriteTimeoutHandler; import reactor.netty.http.client.HttpClient; @Configuration @EnableWebFlux public class WebFluxConfig implements WebFluxConfigurer { Logger logger = LoggerFactory.getLogger(WebFluxConfig.class); @Bean public WebClient getWebClient() { HttpClient httpClient = HttpClient.create() .tcpConfiguration(client -> client.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 10000) .doOnConnected(conn -> conn .addHandlerLast(new ReadTimeoutHandler(10)) .addHandlerLast(new WriteTimeoutHandler(10)))); ClientHttpConnector connector = new ReactorClientHttpConnector(httpClient.wiretap(true)); return WebClient.builder() .baseUrl("http://localhost:3000") .clientConnector(connector) .defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) .build(); } }
2. Set timeout specific to request
To set the timeout specific to a request, its better to use timeout() methods e.g. Mono.timeout(duration)
and Flux.timeout(duration)
.
The timeout()
method in both classes is overloaded with many options. Checkout spring docs for Mono and Flux for more details.
public Flux<Employee> findAll() { return webClient.get() .uri("/employees") .retrieve() .bodyToFlux(Employee.class) .timeout(Duration.ofMillis(10_000)); } public Mono<Employee> create(Employee empl) { return webClient.post() .uri("/employees") .body(Mono.just(empl), Employee.class) .retrieve() .bodyToMono(Employee.class) .timeout(Duration.ofMillis(10_000)); }
Drop me your questions related to setting timeouts in Spring 5 WebClient.
Happy Learning !!
Reference : Spring boot doc
While setting timeouts specific to requests, Is it possible to override the tcp level read and connection timeouts?
How to catch the exception at catch clause? can u add an example of handle? thanks
I liked the explanation Lokesh. I have hard time trying to solve a particular problem. I have two rest calls that need to be made. First one, need to call and forget about it (the call could result in 404, 500 as well, I dont care), while wait for the second rest call for the response. Would you please be able to give pointers to this.
Is second part of post is not applicable? If not, please elaborate more.