From 92b3f2aee7c742ad55bd2ae657937d2f449de5e1 Mon Sep 17 00:00:00 2001 From: Rossen Stoyanchev Date: Thu, 20 Sep 2018 10:37:31 -0400 Subject: [PATCH] Document timeout configuration for Reactor HttpClient Issue: SPR-17241 --- src/docs/asciidoc/web/webflux-webclient.adoc | 69 +++++++++++++++----- 1 file changed, 54 insertions(+), 15 deletions(-) diff --git a/src/docs/asciidoc/web/webflux-webclient.adoc b/src/docs/asciidoc/web/webflux-webclient.adoc index a0b225cef3..b0575c8fca 100644 --- a/src/docs/asciidoc/web/webflux-webclient.adoc +++ b/src/docs/asciidoc/web/webflux-webclient.adoc @@ -1,11 +1,11 @@ [[webflux-client]] = WebClient -Spring WebFlux includes a reactive, non-blocking `WebClient` for performing HTTP requests -using a functional-style API that exposes Reactor `Flux` and `Mono` types, see -<>. The client relies on the same -<> that WebFlux server applications use to work -with request and response content. +Spring WebFlux includes a reactive, non-blocking `WebClient` for HTTP requests. The client +has a functional, fluent API with reactive types for declarative composition, see +<>. WebFlux client and server rely on the +same non-blocking <> to encode and decode request +and response content. Internally `WebClient` delegates to an HTTP client library. By default, it uses https://github.com/reactor/reactor-netty[Reactor Netty], there is built-in support for @@ -22,15 +22,14 @@ The simplest way to create a `WebClient` is through one of the static factory me * `WebClient.create()` * `WebClient.create(String baseUrl)` -The preceding methods use Reactor Netty `HttpClient` from `io.projectreactor.netty:reactor-netty` -with default settings and participates in global resources for event loop threads and -a connection pool. See <>. +The above methods use the Reactor Netty `HttpClient` with default settings and expect +`io.projectreactor.netty:reactor-netty` to be on the classpath. -You can use the `WebClient.Builder` for access to further options: +You can also use `WebClient.builder()` with further options: * `uriBuilderFactory`: Customized `UriBuilderFactory` to use as a base URL. * `defaultHeader`: Headers for every request. -* `defaultCookie)`: Cookies for every request. +* `defaultCookie`: Cookies for every request. * `defaultRequest`: `Consumer` to customize every request. * `filter`: Client filter for every request. * `exchangeStrategies`: HTTP message reader/writer customizations. @@ -78,19 +77,24 @@ modified copy without affecting the original instance, as the following example [[webflux-client-builder-reactor]] === Reactor Netty -You can customize Reactor Netty settings: +To customize Reactor Netty settings, simple provide a pre-configured `HttpClient`: ==== [source,java,intent=0] [subs="verbatim,quotes"] ---- HttpClient httpClient = HttpClient.create().secure(sslSpec -> ...); - ClientHttpConnector connector = new ReactorClientHttpConnector(httpClient); - WebClient webClient = WebClient.builder().clientConnector(connector).build(); + WebClient webClient = WebClient.builder() + .clientConnector(new ReactorClientHttpConnector(httpClient)) + .build(); ---- ==== + +[[webflux-client-builder-reactor-resources]] +==== Resources + By default, `HttpClient` participates in the global Reactor Netty resources held in `reactor.netty.http.HttpResources`, including event loop threads and a connection pool. This is the recommended mode, since fixed, shared resources are preferred for event loop @@ -148,6 +152,41 @@ instances use shared resources, as the following example shows: ==== +[[webflux-client-builder-reactor-timeout]] +==== Timeouts + +To configure a connection timeout: + +==== +[source,java,intent=0] +[subs="verbatim,quotes"] +---- +import io.netty.channel.ChannelOption; + +HttpClient httpClient = HttpClient.create() + .tcpConfiguration(client -> + client.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 10000)); +---- +==== + +To configure a read and/or write timeout values: + +==== +[source,java,intent=0] +[subs="verbatim,quotes"] +---- +import io.netty.handler.timeout.ReadTimeoutHandler; +import io.netty.handler.timeout.WriteTimeoutHandler; + +HttpClient httpClient = HttpClient.create() + .tcpConfiguration(client -> + client.doOnConnected(conn -> conn + .addHandlerLast(new ReadTimeoutHandler(10)) + .addHandlerLast(new WriteTimeoutHandler(10)))); +---- +==== + + [[webflux-client-builder-jetty]] === Jetty @@ -204,7 +243,7 @@ Spring-managed bean of type `JettyResourceFactory`, as the following example sho [[webflux-client-retrieve]] -== Using the `retrieve` Method +== Using `retrieve()` The `retrieve()` method is the easiest way to get a response body and decode it. The following example shows how to do so: @@ -257,7 +296,7 @@ as the following example shows: [[webflux-client-exchange]] -== Using the `exchange` Method +== Using `exchange()` The `exchange()` method provides more control than the `retrieve` method. The following example is equivalent to `retrieve()` but also provides access to the `ClientResponse`: