Skip to content

Commit 6e05a58

Browse files
committed
Update WebClient Javadoc
Issue: SPR-16197
1 parent 7bcbdbb commit 6e05a58

File tree

1 file changed

+105
-79
lines changed
  • spring-webflux/src/main/java/org/springframework/web/reactive/function/client

1 file changed

+105
-79
lines changed

spring-webflux/src/main/java/org/springframework/web/reactive/function/client/WebClient.java

Lines changed: 105 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -40,20 +40,25 @@
4040
import org.springframework.web.reactive.function.BodyInserter;
4141
import org.springframework.web.util.UriBuilder;
4242
import org.springframework.web.util.UriBuilderFactory;
43+
import org.springframework.web.reactive.function.BodyInserters;
4344

4445
/**
45-
* The main entry point for initiating web requests on the client side.
46+
* A non-blocking, reactive client for performing HTTP requests with Reactive
47+
* Streams back pressure. Provides a higher level, common API over HTTP client
48+
* libraries. Reactor Netty is used by default but other clients may be plugged
49+
* in with a {@link ClientHttpConnector}.
4650
*
47-
* <pre class="code">
48-
* // Initialize the client
49-
* WebClient client = WebClient.create("http://abc.com");
51+
* <p>Use one of the static factory methods {@link #create()} or
52+
* {@link #create(String)} or obtain a {@link WebClient#builder()} to create an
53+
* instance.
5054
*
51-
* // Perform requests...
52-
* Mono&#060;String&#062; result = client.get()
53-
* .uri("/foo")
54-
* .exchange()
55-
* .then(response -> response.bodyToMono(String.class));
56-
* </pre>
55+
* <p>For examples with a response body see
56+
* {@link RequestHeadersSpec#retrieve() retrieve()} and
57+
* {@link RequestHeadersSpec#exchange() exchange()}.
58+
* For examples with a request body see
59+
* {@link RequestBodySpec#body(Publisher, Class) body(Publisher,Class)},
60+
* {@link RequestBodySpec#syncBody(Object) syncBody(Object)}, and
61+
* {@link RequestBodySpec#body(BodyInserter) body(BodyInserter)}.
5762
*
5863
* @author Rossen Stoyanchev
5964
* @author Arjen Poutsma
@@ -119,54 +124,17 @@ public interface WebClient {
119124
// Static, factory methods
120125

121126
/**
122-
* Create a new {@code WebClient} with no default, shared preferences across
123-
* requests such as base URI, default headers, and others.
127+
* Create a new {@code WebClient} with a Reactor Netty connector.
124128
* @see #create(String)
129+
* @see #builder()
125130
*/
126131
static WebClient create() {
127132
return new DefaultWebClientBuilder().build();
128133
}
129134

130135
/**
131-
* Configure a base URI for requests performed through the client for
132-
* example to avoid repeating the same host, port, base path, or even
133-
* query parameters with every request.
134-
* <p>For example given this initialization:
135-
* <pre class="code">
136-
* WebClient client = WebClient.create("http://abc.com/v1");
137-
* </pre>
138-
* <p>The base URI is applied to exchanges with a URI template:
139-
* <pre class="code">
140-
* // GET http://abc.com/v1/accounts/43
141-
* Mono&#060;Account&#062; result = client.get()
142-
* .uri("/accounts/{id}", 43)
143-
* .exchange()
144-
* .then(response -> response.bodyToMono(Account.class));
145-
* </pre>
146-
* <p>The base URI is also applied to exchanges with a {@code UriBuilder}:
147-
* <pre class="code">
148-
* // GET http://abc.com/v1/accounts?q=12
149-
* Flux&#060;Account&#062; result = client.get()
150-
* .uri(builder -> builder.path("/accounts").queryParam("q", "12").build())
151-
* .exchange()
152-
* .then(response -> response.bodyToFlux(Account.class));
153-
* </pre>
154-
* <p>The base URI can be overridden with an absolute URI:
155-
* <pre class="code">
156-
* // GET http://xyz.com/path
157-
* Mono&#060;Account&#062; result = client.get()
158-
* .uri("http://xyz.com/path")
159-
* .exchange()
160-
* .then(response -> response.bodyToMono(Account.class));
161-
* </pre>
162-
* <p>The base URI can be partially overridden with a {@code UriBuilder}:
163-
* <pre class="code">
164-
* // GET http://abc.com/v2/accounts?q=12
165-
* Flux&#060;Account&#062; result = client.get()
166-
* .uri(builder -> builder.replacePath("/v2/accounts").queryParam("q", "12").build())
167-
* .exchange()
168-
* .then(response -> response.bodyToFlux(Account.class));
169-
* </pre>
136+
* A variant of {@link #create()} that accepts a default base URL. For more
137+
* details see {@link Builder#baseUrl(String) Builder.baseUrl(String)}.
170138
* @param baseUrl the base URI for all requests
171139
*/
172140
static WebClient create(String baseUrl) {
@@ -182,13 +150,50 @@ static WebClient.Builder builder() {
182150

183151

184152
/**
185-
* A mutable builder for a {@link WebClient}.
153+
* A mutable builder for creating a {@link WebClient}.
186154
*/
187155
interface Builder {
188156

189157
/**
190-
* Configure a base URI as described in {@link WebClient#create(String)
191-
* WebClient.create(String)}.
158+
* Configure a base URL for requests performed through the client.
159+
*
160+
* <p>For example given base URL "http://abc.com/v1":
161+
* <p><pre class="code">
162+
* Mono&#060;Account&#062; result = client.get()
163+
* .uri("/accounts/{id}", 43)
164+
* .exchange()
165+
* .then(response -> response.bodyToMono(Account.class));
166+
*
167+
* // Result: http://abc.com/v1/accounts/43
168+
*
169+
* Flux&#060;Account&#062; result = client.get()
170+
* .uri(builder -> builder.path("/accounts").queryParam("q", "12").build())
171+
* .exchange()
172+
* .then(response -> response.bodyToFlux(Account.class));
173+
*
174+
* // Result: http://abc.com/v1/accounts?q=12
175+
* </pre>
176+
*
177+
* <p>The base URL can be overridden with an absolute URI:
178+
* <pre class="code">
179+
* Mono&#060;Account&#062; result = client.get()
180+
* .uri("http://xyz.com/path")
181+
* .exchange()
182+
* .then(response -> response.bodyToMono(Account.class));
183+
*
184+
* // Result: http://xyz.com/path
185+
* </pre>
186+
*
187+
* <p>Or partially overridden with a {@code UriBuilder}:
188+
* <pre class="code">
189+
* Flux&#060;Account&#062; result = client.get()
190+
* .uri(builder -> builder.replacePath("/v2/accounts").queryParam("q", "12").build())
191+
* .exchange()
192+
* .then(response -> response.bodyToFlux(Account.class));
193+
*
194+
* // Result: http://abc.com/v2/accounts?q=12
195+
* </pre>
196+
*
192197
* @see #defaultUriVariables(Map)
193198
* @see #uriBuilderFactory(UriBuilderFactory)
194199
*/
@@ -510,51 +515,72 @@ interface RequestBodySpec extends RequestHeadersSpec<RequestBodySpec> {
510515
RequestBodySpec contentType(MediaType contentType);
511516

512517
/**
513-
* Set the body of the request to the given {@code BodyInserter}.
514-
* @param inserter the {@code BodyInserter} that writes to the request
518+
* Set the body of the request using the given body inserter.
519+
* {@link BodyInserters} provides access to built-in implementations of
520+
* {@link BodyInserter}.
521+
* @param inserter the body inserter to use for the request body
515522
* @return this builder
523+
* @see org.springframework.web.reactive.function.BodyInserters
516524
*/
517525
RequestHeadersSpec<?> body(BodyInserter<?, ? super ClientHttpRequest> inserter);
518526

519527
/**
520-
* Set the body of the request to the given asynchronous {@code Publisher}.
521-
* <p>This method is a convenient shortcut for {@link #body(BodyInserter)} with a
522-
* {@linkplain org.springframework.web.reactive.function.BodyInserters#fromPublisher}
523-
* Publisher body inserter}.
528+
* A shortcut for {@link #body(BodyInserter)} with a
529+
* {@linkplain BodyInserters#fromPublisher Publisher inserter}.
530+
* For example:
531+
* <p><pre>
532+
* Mono<Person> personMono = ... ;
533+
*
534+
* Mono<Void> result = client.post()
535+
* .uri("/persons/{id}", id)
536+
* .contentType(MediaType.APPLICATION_JSON)
537+
* .body(personMono, Person.class)
538+
* .retrieve()
539+
* .bodyToMono(Void.class);
540+
* </pre>
524541
* @param publisher the {@code Publisher} to write to the request
525-
* @param typeReference the type reference of elements contained in the publisher
542+
* @param elementClass the class of elements contained in the publisher
526543
* @param <T> the type of the elements contained in the publisher
527544
* @param <P> the type of the {@code Publisher}
528545
* @return this builder
529546
*/
530-
<T, P extends Publisher<T>> RequestHeadersSpec<?> body(P publisher, ParameterizedTypeReference<T> typeReference);
547+
<T, P extends Publisher<T>> RequestHeadersSpec<?> body(P publisher, Class<T> elementClass);
531548

532549
/**
533-
* Set the body of the request to the given asynchronous {@code Publisher}.
534-
* <p>This method is a convenient shortcut for {@link #body(BodyInserter)} with a
535-
* {@linkplain org.springframework.web.reactive.function.BodyInserters#fromPublisher}
536-
* Publisher body inserter}.
550+
* A variant of {@link #body(Publisher, Class)} that allows providing
551+
* element type information that includes generics via a
552+
* {@link ParameterizedTypeReference}.
537553
* @param publisher the {@code Publisher} to write to the request
538-
* @param elementClass the class of elements contained in the publisher
554+
* @param typeReference the type reference of elements contained in the publisher
539555
* @param <T> the type of the elements contained in the publisher
540556
* @param <P> the type of the {@code Publisher}
541557
* @return this builder
542558
*/
543-
<T, P extends Publisher<T>> RequestHeadersSpec<?> body(P publisher, Class<T> elementClass);
559+
<T, P extends Publisher<T>> RequestHeadersSpec<?> body(P publisher,
560+
ParameterizedTypeReference<T> typeReference);
544561

545562
/**
546-
* Set the body of the request to the given synchronous {@code Object}.
547-
* <p>This method is a convenient shortcut for:
548-
* <pre class="code">
549-
* .body(BodyInserters.fromObject(object))
563+
* A shortcut for {@link #body(BodyInserter)} with an
564+
* {@linkplain BodyInserters#fromObject Object inserter}.
565+
* For example:
566+
* <p><pre class="code">
567+
* Person person = ... ;
568+
*
569+
* Mono<Void> result = client.post()
570+
* .uri("/persons/{id}", id)
571+
* .contentType(MediaType.APPLICATION_JSON)
572+
* .syncBody(person)
573+
* .retrieve()
574+
* .bodyToMono(Void.class);
550575
* </pre>
551-
* <p>The body can be a
552-
* {@link org.springframework.util.MultiValueMap MultiValueMap} to create
553-
* a multipart request. The values in the {@code MultiValueMap} can be
554-
* any Object representing the body of the part, or an
555-
* {@link org.springframework.http.HttpEntity HttpEntity} representing a
556-
* part with body and headers. The {@code MultiValueMap} can be built
557-
* conveniently using
576+
* <p>For multipart requests, provide a
577+
* {@link org.springframework.util.MultiValueMap MultiValueMap}. The
578+
* values in the {@code MultiValueMap} can be any Object representing
579+
* the body of the part, or an
580+
* {@link org.springframework.http.HttpEntity HttpEntity} representing
581+
* a part with body and headers. The {@code MultiValueMap} can be built
582+
* with {@link org.springframework.http.client.MultipartBodyBuilder
583+
* MultipartBodyBuilder}.
558584
* @param body the {@code Object} to write to the request
559585
* @return this builder
560586
*/

0 commit comments

Comments
 (0)