@@ -12,19 +12,34 @@ a number of technologies.
12
12
13
13
14
14
[[rest-client-access]]
15
- == REST Endpoints
15
+ == REST Clients
16
16
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.
18
41
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.
23
42
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.
28
43
29
44
30
45
[[rest-resttemplate]]
@@ -34,6 +49,10 @@ The `RestTemplate` provides a higher level API over HTTP client libraries. It ma
34
49
easy to invoke REST endpoints in a single line. It exposes the following groups of
35
50
overloaded methods:
36
51
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
+
37
56
[[rest-overview-of-resttemplate-methods-tbl]]
38
57
.RestTemplate methods
39
58
[cols="1,3"]
@@ -344,6 +363,151 @@ to `multipart/form-data` by the `FormHttpMessageConverter`. If the `MultiValueMa
344
363
If necessary the `Content-Type` may also be set explicitly.
345
364
346
365
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
+
347
511
348
512
349
513
[[jms]]
0 commit comments