Skip to content

Commit

Permalink
Revise docs for server use of @HttpExchange
Browse files Browse the repository at this point in the history
Closes gh-30980
  • Loading branch information
rstoyanchev committed Aug 4, 2023
1 parent 6630b16 commit 5115684
Show file tree
Hide file tree
Showing 8 changed files with 166 additions and 448 deletions.
28 changes: 15 additions & 13 deletions framework-docs/modules/ROOT/pages/integration/rest-clients.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -363,12 +363,13 @@ If necessary the `Content-Type` may also be set explicitly.
[[rest-http-interface]]
== HTTP Interface

The Spring Framework lets you define an HTTP service as a Java interface with annotated
methods for HTTP exchanges. You can then generate a proxy that implements this interface
and performs the exchanges. This helps to simplify HTTP remote access which often
involves a facade that wraps the details of using the underlying HTTP client.
The Spring Framework lets you define an HTTP service as a Java interface with
`@HttpExchange` methods. You can pass such an interface to `HttpServiceProxyFactory`
to create a proxy which performs requests through an HTTP client such as `RestClient`
or `WebClient`. You can also implement the interface from an `@Controller` for server
request handling.

One, declare an interface with `@HttpExchange` methods:
Start by creating the interface with `@HttpExchange` methods:

[source,java,indent=0,subs="verbatim,quotes"]
----
Expand All @@ -382,30 +383,31 @@ One, declare an interface with `@HttpExchange` methods:
}
----

Two, create a proxy that will perform the declared HTTP exchanges,
either using `WebClient`:
Now you can create a proxy that performs requests when methods are called.

For `RestClient`:

[source,java,indent=0,subs="verbatim,quotes"]
----
WebClient client = WebClient.builder().baseUrl("https://api.github.com/").build();
WebClientAdapter adapter = WebClientAdapter.forClient(webClient)
RestClient restClient = RestClient.builder().baseUrl("https://api.github.com/").build();
RestClientAdapter adapter = RestClientAdapter.create(restClient);
HttpServiceProxyFactory factory = HttpServiceProxyFactory.builderFor(adapter).build();
RepositoryService service = factory.createClient(RepositoryService.class);
----

using `RestClient`:
For `WebClient`:

[source,java,indent=0,subs="verbatim,quotes"]
----
RestClient restClient = RestClient.builder().baseUrl("https://api.github.com/").build();
RestClientAdapter adapter = RestClientAdapter.create(restClient);
WebClient client = WebClient.builder().baseUrl("https://api.github.com/").build();
WebClientAdapter adapter = WebClientAdapter.forClient(webClient)
HttpServiceProxyFactory factory = HttpServiceProxyFactory.builderFor(adapter).build();
RepositoryService service = factory.createClient(RepositoryService.class);
----

or using `RestTemplate`:
For `RestTemplate`:

[source,java,indent=0,subs="verbatim,quotes"]
----
Expand Down
2 changes: 1 addition & 1 deletion framework-docs/modules/ROOT/pages/rsocket.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -871,7 +871,7 @@ interaction type(s):
As an alternative to `@MessageMapping`, you can also handle requests with
`@RSocketExchange` methods. Such methods are declared on an
xref:rsocket-interface[RSocket Interface] and can be used as a requester via
`RSocketServiceProxyFactory` or as a responder.
`RSocketServiceProxyFactory` or implemented by a responder.

For example, to handle requests as a responder:

Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

[.small]#xref:web/webmvc/mvc-controller/ann-methods.adoc[See equivalent in the Servlet stack]#

`@RequestMapping` and `@HttpExchange` handler methods have a flexible signature and can choose from a range of
`@RequestMapping` handler methods have a flexible signature and can choose from a range of
supported controller method arguments and return values.


Original file line number Diff line number Diff line change
@@ -1,8 +1,15 @@
[[webflux-ann-requestmapping]]
= Request Mapping
= Mapping Requests

[.small]#xref:web/webmvc/mvc-controller/ann-requestmapping.adoc[See equivalent in the Servlet stack]#

This section discusses request mapping for annotated controllers.

[[webflux-ann-requestmapping-annotation]]
== `@RequestMapping`

[.small]#xref:web/webmvc/mvc-controller/ann-requestmapping.adoc#mvc-ann-requestmapping-annotation[See equivalent in the Servlet stack]#

The `@RequestMapping` annotation is used to map requests to controllers methods. It has
various attributes to match by URL, HTTP method, request parameters, headers, and media
types. You can use it at the class level to express shared mappings or at the method level
Expand Down Expand Up @@ -500,3 +507,68 @@ Kotlin::



[[webflux-ann-httpexchange-annotation]]
== `@HttpExchange`
[.small]#xref:web/webmvc/mvc-controller/ann-requestmapping.adoc#mvc-ann-httpexchange-annotation[See equivalent in the Reactive stack]#

As an alternative to `@RequestMapping`, you can also handle requests with `@HttpExchange`
methods. Such methods are declared on an
xref:integration/rest-clients.adoc#rest-http-interface[HTTP Interface] and can be used as
a client via `HttpServiceProxyFactory` or implemented by a server `@Controller`.

For example:

[tabs]
======
Java::
+
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
----
@RestController
@HttpExchange("/persons")
class PersonController {
@GetExchange("/{id}")
public Person getPerson(@PathVariable Long id) {
// ...
}
@PostExchange
@ResponseStatus(HttpStatus.CREATED)
public void add(@RequestBody Person person) {
// ...
}
}
----
Kotlin::
+
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
----
@RestController
@HttpExchange("/persons")
class PersonController {
@GetExchange("/{id}")
fun getPerson(@PathVariable id: Long): Person {
// ...
}
@PostExchange
@ResponseStatus(HttpStatus.CREATED)
fun add(@RequestBody person: Person) {
// ...
}
}
----
======

There some differences between `@HttpExchange` and `@RequestMapping` since the
former needs to remain suitable for client and server use. For example, while
`@RequestMapping` can be declared to handle any number of paths and each path can
be a pattern, `@HttpExchange` must be declared with a single, concrete path. There are
also differences in the supported method parameters. Generally, `@HttpExchange` supports
a subset of method parameters that `@RequestMapping` does, excluding any parameters that
are server side only. For details see the list of supported method parameters for
xref:integration/rest-clients.adoc#rest-http-interface-method-parameters[HTTP interface] and for
xref:web/webflux/controller/ann-methods/arguments.adoc[@RequestMapping].
Loading

0 comments on commit 5115684

Please sign in to comment.