public class ProxyExchange<T> extends Object
@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 "sensitive" headers). To manipulate the downstream
request there are "builder" style methods in ProxyExchange
, but only the
uri(String)
is mandatory. You can change the sensitive headers by calling the
sensitive(String...)
method (Authorization and Cookie are sensitive by
default).
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).
Modifier and Type | Class and Description |
---|---|
protected static class |
ProxyExchange.BodyGrabber |
protected static class |
ProxyExchange.BodySender |
Modifier and Type | Field and Description |
---|---|
static Set<String> |
DEFAULT_SENSITIVE
Contains headers that are considered case-sensitive by default.
|
Constructor and Description |
---|
ProxyExchange(org.springframework.web.reactive.function.client.WebClient rest,
org.springframework.web.server.ServerWebExchange exchange,
org.springframework.web.reactive.BindingContext bindingContext,
Type type) |
Modifier and Type | Method and Description |
---|---|
ProxyExchange<T> |
body(Object body)
|
ProxyExchange<T> |
body(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) |
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) |
ProxyExchange<T> |
header(String name,
String... value)
Sets a header for the downstream call.
|
ProxyExchange<T> |
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) |
String |
path() |
String |
path(String prefix) |
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) |
ProxyExchange<T> |
sensitive(String... names)
Sets the names of sensitive headers that are not passed downstream to the backend
service.
|
ProxyExchange<T> |
uri(String uri)
Sets the uri for the backend call when triggered by the HTTP methods.
|
public ProxyExchange(org.springframework.web.reactive.function.client.WebClient rest, org.springframework.web.server.ServerWebExchange exchange, org.springframework.web.reactive.BindingContext bindingContext, Type type)
public ProxyExchange<T> body(Object body)
post()
, put()
or patch()
). 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 @RequestBody
in your
@RequestMapping
in the usual Spring MVC way.body
- the request body to send downstreampublic ProxyExchange<T> body(org.reactivestreams.Publisher<?> body)
post()
, put()
or patch()
). 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 @RequestBody
in your
@RequestMapping
in the usual Spring MVC way.body
- the request body to send downstreampublic ProxyExchange<T> header(String name, String... value)
name
- Header namevalue
- Header valuespublic ProxyExchange<T> headers(org.springframework.http.HttpHeaders headers)
headers
- the http headers to use in the downstream callpublic ProxyExchange<T> sensitive(String... names)
names
- the names of sensitive headerspublic ProxyExchange<T> uri(String uri)
uri
- the backend uri to send the request topublic String path()
public reactor.core.publisher.Mono<org.springframework.http.ResponseEntity<T>> get()
public <S> reactor.core.publisher.Mono<org.springframework.http.ResponseEntity<S>> get(Function<org.springframework.http.ResponseEntity<T>,org.springframework.http.ResponseEntity<S>> converter)
public reactor.core.publisher.Mono<org.springframework.http.ResponseEntity<T>> head()
public <S> reactor.core.publisher.Mono<org.springframework.http.ResponseEntity<S>> head(Function<org.springframework.http.ResponseEntity<T>,org.springframework.http.ResponseEntity<S>> converter)
public reactor.core.publisher.Mono<org.springframework.http.ResponseEntity<T>> options()
public <S> reactor.core.publisher.Mono<org.springframework.http.ResponseEntity<S>> options(Function<org.springframework.http.ResponseEntity<T>,org.springframework.http.ResponseEntity<S>> converter)
public reactor.core.publisher.Mono<org.springframework.http.ResponseEntity<T>> post()
public <S> reactor.core.publisher.Mono<org.springframework.http.ResponseEntity<S>> post(Function<org.springframework.http.ResponseEntity<T>,org.springframework.http.ResponseEntity<S>> converter)
public reactor.core.publisher.Mono<org.springframework.http.ResponseEntity<T>> delete()
public <S> reactor.core.publisher.Mono<org.springframework.http.ResponseEntity<S>> delete(Function<org.springframework.http.ResponseEntity<T>,org.springframework.http.ResponseEntity<S>> converter)
public reactor.core.publisher.Mono<org.springframework.http.ResponseEntity<T>> put()
public <S> reactor.core.publisher.Mono<org.springframework.http.ResponseEntity<S>> put(Function<org.springframework.http.ResponseEntity<T>,org.springframework.http.ResponseEntity<S>> converter)
public reactor.core.publisher.Mono<org.springframework.http.ResponseEntity<T>> patch()
public <S> reactor.core.publisher.Mono<org.springframework.http.ResponseEntity<S>> patch(Function<org.springframework.http.ResponseEntity<T>,org.springframework.http.ResponseEntity<S>> converter)
public reactor.core.publisher.Mono<org.springframework.http.ResponseEntity<T>> forward()
Copyright © 2020 Pivotal Software, Inc.. All rights reserved.