@@ -12,19 +12,34 @@ a number of technologies.
1212
1313
1414[[rest-client-access]]
15- == REST Endpoints
15+ == REST Clients
1616
17- The Spring Framework provides two choices for making calls to REST endpoints:
17+ The Spring Framework provides the following choices for making calls to REST endpoints:
18+
19+ * <<rest-webclient>> - non-blocking, reactive client w fluent API.
20+ * <<rest-resttemplate>> - synchronous client with template method API.
21+ * <<rest-http-interface>> - annotated interface with generated, dynamic proxy implementation.
22+
23+
24+ [[rest-webclient]]
25+ === `WebClient`
26+
27+ `WebClient` is a non-blocking, reactive client to perform HTTP requests. It was
28+ introduced in 5.0 and offers an alternative to the `RestTemplate`, with support for
29+ synchronous, asynchronous, and streaming scenarios.
30+
31+ `WebClient` supports the following:
32+
33+ * Non-blocking I/O.
34+ * Reactive Streams back pressure.
35+ * High concurrency with fewer hardware resources.
36+ * Functional-style, fluent API that takes advantage of Java 8 lambdas.
37+ * Synchronous and asynchronous interactions.
38+ * Streaming up to or streaming down from a server.
39+
40+ See <<web-reactive.adoc#webflux-client, WebClient>> for more details.
1841
19- * <<rest-resttemplate>>: The original Spring REST client with a synchronous, template
20- method API.
21- * <<web-reactive.adoc#webflux-client, WebClient>>: a non-blocking, reactive alternative
22- that supports both synchronous and asynchronous as well as streaming scenarios.
2342
24- NOTE: As of 5.0 the `RestTemplate` is in maintenance mode, with only minor requests for
25- changes and bugs to be accepted going forward. Please, consider using the
26- <<web-reactive.adoc#webflux-client, WebClient>> which offers a more modern API and
27- supports sync, async, and streaming scenarios.
2843
2944
3045[[rest-resttemplate]]
@@ -34,6 +49,10 @@ The `RestTemplate` provides a higher level API over HTTP client libraries. It ma
3449easy to invoke REST endpoints in a single line. It exposes the following groups of
3550overloaded methods:
3651
52+ NOTE: `RestTemplate` is in maintenance mode, with only requests for minor
53+ changes and bugs to be accepted. Please, consider using the
54+ <<web-reactive.adoc#webflux-client, WebClient>> instead.
55+
3756[[rest-overview-of-resttemplate-methods-tbl]]
3857.RestTemplate methods
3958[cols="1,3"]
@@ -344,6 +363,151 @@ to `multipart/form-data` by the `FormHttpMessageConverter`. If the `MultiValueMa
344363If necessary the `Content-Type` may also be set explicitly.
345364
346365
366+ [[rest-http-interface]]
367+ === HTTP Interface
368+
369+ The Spring Frameworks lets you define an HTTP service as a Java interface with annotated
370+ methods for HTTP exchanges. You can then generate a proxy that implements this interface
371+ and performs the exchanges. This helps to simplify HTTP remote access which often
372+ involves a facade that wraps the details of using the underlying HTTP client.
373+
374+ To start, declare an interface with annotated, HTTP exchange methods:
375+
376+ [source,java,indent=0,subs="verbatim,quotes"]
377+ ----
378+ interface RepositoryService {
379+
380+ @GetExchange("/repos/{owner}/{repo}")
381+ Repository getRepository(@PathVariable String owner, @PathVariable String repo);
382+
383+ // more HTTP exchange methods...
384+
385+ }
386+ ----
387+
388+ Now you create a proxy for the interface that performs the declared exchanges through
389+ the `WebClient`:
390+
391+ [source,java,indent=0,subs="verbatim,quotes"]
392+ ----
393+ WebClient client = WebClient.builder()
394+ .baseUrl("https://api.github.com/")
395+ .build();
396+
397+ HttpServiceProxyFactory proxyFactory =
398+ HttpServiceProxyFactory.builder(new WebClientAdapter(client)).build();
399+
400+ RepositoryService service = proxyFactory.createClient(RepositoryService.class);
401+ ----
402+
403+ An HTTP service interface can declare common attributes at the type level:
404+
405+ [source,java,indent=0,subs="verbatim,quotes"]
406+ ----
407+ @HttpExchange(url = "/repos/{owner}/{repo}", accept = "application/vnd.github.v3+json")
408+ interface RepositoryService {
409+
410+ @GetExchange
411+ Repository getRepository(@PathVariable String owner, @PathVariable String repo);
412+
413+ @PatchExchange(contentType = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
414+ void updateRepository(@PathVariable String owner, @PathVariable String repo,
415+ @RequestParam String name, @RequestParam String description, @RequestParam String homepage);
416+
417+ }
418+ ----
419+
420+
421+ [[rest-http-interface-method-parameters]]
422+ ==== Method Parameters
423+
424+ Annotated, HTTP exchange methods support flexible method signatures with the following
425+ method parameters:
426+
427+ [cols="1,2", options="header"]
428+ |===
429+ | Controller method argument | Description
430+
431+ | `URI`
432+ | Dynamically set the URL for the request, overriding the annotation's `url` attribute.
433+
434+ | `HttpMethod`
435+ | Dynamically set the HTTP method for the request, overriding the annotation's `method` attribute
436+
437+ | `@RequestHeader`
438+ | Add a request header or mutliple headers. The argument may be a `Map<String, ?>` or
439+ `MultiValueMap<String, ?>` with multiple headers, a `Collection<?>` of values, or an
440+ individual value. Type conversion is supported for non-String values.
441+
442+ | `@PathVariable`
443+ | Add a variable for expand a placeholder in the request URL. The argument may be a
444+ `Map<String, ?>` with multiple variables, or an individual value. Type conversion
445+ is supported for non-String values.
446+
447+ | `@RequestBody`
448+ | Provide the body of the request either as an Object to be serialized, or a
449+ Reactive Streams `Publisher` such as `Mono`, `Flux`, or any other async type supported
450+ through the configured `ReactiveAdapterRegistry`.
451+
452+ | `@RequestParam`
453+ | Add a request parameter or mutliple parameters. The argument may be a `Map<String, ?>`
454+ or `MultiValueMap<String, ?>` with multiple parameters, a `Collection<?>` of values, or
455+ an individual value. Type conversion is supported for non-String values.
456+
457+ When `"content-type"` is set to `"application/x-www-form-urlencoded"`, request
458+ parameters are encoded in the request body. Otherwise, they are added as URL query
459+ parameters.
460+
461+ | `@CookieValue`
462+ | Add a cookie or mutliple cookies. The argument may be a `Map<String, ?>` or
463+ `MultiValueMap<String, ?>` with multiple cookies, a `Collection<?>` of values, or an
464+ individual value. Type conversion is supported for non-String values.
465+
466+ |===
467+
468+
469+ [[rest-http-interface-return-values]]
470+ ==== Return Values
471+
472+ Annotated, HTTP exchange methods support the following return values:
473+
474+ [cols="1,2", options="header"]
475+ |===
476+ | Controller method return value | Description
477+
478+ | `void`, `Mono<Void>`
479+ | Perform the given request, and release the response content, if any.
480+
481+ | `HttpHeaders`, `Mono<HttpHeaders>`
482+ | Perform the given request, release the response content, if any, and return the
483+ response headers.
484+
485+ | `<T>`, `Mono<T>`
486+ | Perform the given request and decode the response content to the declared return type.
487+
488+ | `<T>`, `Flux<T>`
489+ | Perform the given request and decode the response content to a stream of the declared
490+ element type.
491+
492+ | `ResponseEntity<Void>`, `Mono<ResponseEntity<Void>>`
493+ | Perform the given request, and release the response content, if any, and return a
494+ `ResponseEntity` with the status and headers.
495+
496+ | `ResponseEntity<T>`, `Mono<ResponseEntity<T>>`
497+ | Perform the given request, decode the response content to the declared return type, and
498+ return a `ResponseEntity` with the status, headers, and the decoded body.
499+
500+ | `Mono<ResponseEntity<Flux<T>>`
501+ | Perform the given request, decode the response content to a stream of the declared
502+ element type, and return a `ResponseEntity` with the status, headers, and the decoded
503+ response body stream.
504+
505+ |===
506+
507+ TIP: You can also use any other async or reactive types registered in the
508+ `ReactiveAdapterRegistry`.
509+
510+
347511
348512
349513[[jms]]
0 commit comments