Class ProxyExchange<T>
@RequestMapping argument type that can proxy the request to a backend.
Spring will inject one of these into your MVC handler method, and you get return a
ResponseEntity that you get from one of the HTTP methods get(),
post(), put(), patch(), delete() etc. Example:
@GetMapping("/proxy/{id}")
public Mono<ResponseEntity<?>> proxy(@PathVariable Integer id, ProxyExchange<?> proxy)
throws Exception {
return proxy.uri("http://localhost:9000/foos/" + id).get();
}
By default the incoming request body and headers are sent intact to the downstream
service (with the exception of "excluded" headers). To manipulate the downstream
request there are "builder" style methods in ProxyExchange, but only the
uri(String) is mandatory. You can change the excluded headers by calling the
excluded(String...) method (the argument resolver will populate these with
some sensible defaults).
The type parameter T in ProxyExchange<T> is the type of
the response body, so it comes out in the ResponseEntity that you return from
your @RequestMapping. If you don't care about the type of the request and
response body (e.g. if it's just a passthru) then use a wildcard, or
byte[] (Object probably won't work unless you provide a
converter). Use a concrete type if you want to transform or manipulate the response, or
if you want to assert that it is convertible to the type you declare.
To manipulate the response use the overloaded HTTP methods with a Function
argument and pass in code to transform the response. E.g.
@PostMapping("/proxy")
public Mono<ResponseEntity<Foo>> proxy(ProxyExchange<Foo> proxy) throws Exception {
return proxy.uri("http://localhost:9000/foos/") //
.post(response -> ResponseEntity.status(response.getStatusCode()) //
.headers(response.getHeaders()) //
.header("X-Custom", "MyCustomHeader") //
.body(response.getBody()) //
);
}
The full machinery of Spring message converters is applied
to the incoming request and response and also to the backend request. If you need
additional converters then they need to be added upstream in the MVC configuration and
also to the WebClient that is used in the backend calls (see the
constructor for details).
- Author:
- Dave Syer
-
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionprotected static classprotected static class -
Field Summary
Fields -
Constructor Summary
ConstructorsConstructorDescriptionProxyExchange(org.springframework.web.reactive.function.client.WebClient rest, org.springframework.web.server.ServerWebExchange exchange, org.springframework.web.reactive.BindingContext bindingContext, Type type) -
Method Summary
Modifier and TypeMethodDescriptionbody(org.reactivestreams.Publisher<?> body) reactor.core.publisher.Mono<org.springframework.http.ResponseEntity<T>>delete()<S> reactor.core.publisher.Mono<org.springframework.http.ResponseEntity<S>>delete(Function<org.springframework.http.ResponseEntity<T>, org.springframework.http.ResponseEntity<S>> converter) Sets the names of excluded headers that are not passed downstream to the backend service.reactor.core.publisher.Mono<org.springframework.http.ResponseEntity<T>>forward()<S> reactor.core.publisher.Mono<org.springframework.http.ResponseEntity<S>>forward(Function<org.springframework.http.ResponseEntity<T>, org.springframework.http.ResponseEntity<S>> converter) reactor.core.publisher.Mono<org.springframework.http.ResponseEntity<T>>get()<S> reactor.core.publisher.Mono<org.springframework.http.ResponseEntity<S>>get(Function<org.springframework.http.ResponseEntity<T>, org.springframework.http.ResponseEntity<S>> converter) reactor.core.publisher.Mono<org.springframework.http.ResponseEntity<T>>head()<S> reactor.core.publisher.Mono<org.springframework.http.ResponseEntity<S>>head(Function<org.springframework.http.ResponseEntity<T>, org.springframework.http.ResponseEntity<S>> converter) Sets a header for the downstream call.headers(org.springframework.http.HttpHeaders headers) Additional headers, or overrides of the incoming ones, to be used in the downstream call.reactor.core.publisher.Mono<org.springframework.http.ResponseEntity<T>>options()<S> reactor.core.publisher.Mono<org.springframework.http.ResponseEntity<S>>options(Function<org.springframework.http.ResponseEntity<T>, org.springframework.http.ResponseEntity<S>> converter) reactor.core.publisher.Mono<org.springframework.http.ResponseEntity<T>>patch()<S> reactor.core.publisher.Mono<org.springframework.http.ResponseEntity<S>>patch(Function<org.springframework.http.ResponseEntity<T>, org.springframework.http.ResponseEntity<S>> converter) path()reactor.core.publisher.Mono<org.springframework.http.ResponseEntity<T>>post()<S> reactor.core.publisher.Mono<org.springframework.http.ResponseEntity<S>>post(Function<org.springframework.http.ResponseEntity<T>, org.springframework.http.ResponseEntity<S>> converter) reactor.core.publisher.Mono<org.springframework.http.ResponseEntity<T>>put()<S> reactor.core.publisher.Mono<org.springframework.http.ResponseEntity<S>>put(Function<org.springframework.http.ResponseEntity<T>, org.springframework.http.ResponseEntity<S>> converter) Deprecated.Sets the uri for the backend call when triggered by the HTTP methods.
-
Field Details
-
DEFAULT_SENSITIVE
Deprecated.Contains headers that are considered case-sensitive by default.
-
-
Constructor Details
-
ProxyExchange
public ProxyExchange(org.springframework.web.reactive.function.client.WebClient rest, org.springframework.web.server.ServerWebExchange exchange, org.springframework.web.reactive.BindingContext bindingContext, Type type)
-
-
Method Details
-
body
Sets the body for the downstream request (if usingpost(),put()orpatch()). The body can be omitted if you just want to pass the incoming request downstream without changing it. If you want to transform the incoming request you can declare it as a@RequestBodyin your@RequestMappingin the usual Spring MVC way.- Parameters:
body- the request body to send downstream- Returns:
- this for convenience
-
body
Sets the body for the downstream request (if usingpost(),put()orpatch()). The body can be omitted if you just want to pass the incoming request downstream without changing it. If you want to transform the incoming request you can declare it as a@RequestBodyin your@RequestMappingin the usual Spring MVC way.- Parameters:
body- the request body to send downstream- Returns:
- this for convenience
-
header
Sets a header for the downstream call.- Parameters:
name- Header namevalue- Header values- Returns:
- this for convenience
-
headers
Additional headers, or overrides of the incoming ones, to be used in the downstream call.- Parameters:
headers- the http headers to use in the downstream call- Returns:
- this for convenience
-
sensitive
Deprecated.Sets the names of sensitive headers that are not passed downstream to the backend service.- Parameters:
names- the names of sensitive headers- Returns:
- this for convenience
-
excluded
Sets the names of excluded headers that are not passed downstream to the backend service.- Parameters:
names- the names of excluded headers- Returns:
- this for convenience
-
uri
Sets the uri for the backend call when triggered by the HTTP methods.- Parameters:
uri- the backend uri to send the request to- Returns:
- this for convenience
-
path
-
path
-
get
-
get
-
head
-
head
-
options
-
options
-
post
-
post
-
delete
-
delete
-
put
-
put
-
patch
-
patch
-
forward
-
forward
-
ProxyProperties.DEFAULT_SENSITIVE