Class ProxyExchange<T>

java.lang.Object
org.springframework.cloud.gateway.mvc.ProxyExchange<T>

public class ProxyExchange<T> extends Object
A @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 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[] or Object. 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 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 RestTemplate that is used in the backend calls (see the constructor for details).

As well as the HTTP methods for a backend call you can also use forward(String) for a local in-container dispatch.

Author:
Dave Syer
  • Nested Class Summary

    Nested Classes
    Modifier and Type
    Class
    Description
    protected static class 
     
    protected static class 
     
  • Field Summary

    Fields
    Modifier and Type
    Field
    Description
    static Set<String>
    Contains headers that are considered case-sensitive by default.
  • Constructor Summary

    Constructors
    Constructor
    Description
    ProxyExchange(org.springframework.web.client.RestTemplate rest, org.springframework.web.context.request.NativeWebRequest webRequest, org.springframework.web.method.support.ModelAndViewContainer mavContainer, org.springframework.web.bind.support.WebDataBinderFactory binderFactory, Type type)
     
  • Method Summary

    Modifier and Type
    Method
    Description
    body(Object body)
    Sets the body for the downstream request (if using post(), put() or patch()).
    org.springframework.http.ResponseEntity<T>
     
    <S> org.springframework.http.ResponseEntity<S>
    delete(Function<org.springframework.http.ResponseEntity<T>,org.springframework.http.ResponseEntity<S>> converter)
     
    void
     
    org.springframework.http.ResponseEntity<T>
    get()
     
    <S> org.springframework.http.ResponseEntity<S>
    get(Function<org.springframework.http.ResponseEntity<T>,org.springframework.http.ResponseEntity<S>> converter)
     
    org.springframework.http.ResponseEntity<T>
     
    <S> org.springframework.http.ResponseEntity<S>
    head(Function<org.springframework.http.ResponseEntity<T>,org.springframework.http.ResponseEntity<S>> converter)
     
    header(String name, String... value)
    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.
    org.springframework.http.ResponseEntity<T>
     
    <S> org.springframework.http.ResponseEntity<S>
    options(Function<org.springframework.http.ResponseEntity<T>,org.springframework.http.ResponseEntity<S>> converter)
     
    org.springframework.http.ResponseEntity<T>
     
    <S> org.springframework.http.ResponseEntity<S>
    patch(Function<org.springframework.http.ResponseEntity<T>,org.springframework.http.ResponseEntity<S>> converter)
     
     
    path(String prefix)
     
    org.springframework.http.ResponseEntity<T>
     
    <S> org.springframework.http.ResponseEntity<S>
    post(Function<org.springframework.http.ResponseEntity<T>,org.springframework.http.ResponseEntity<S>> converter)
     
    org.springframework.http.ResponseEntity<T>
    put()
     
    <S> org.springframework.http.ResponseEntity<S>
    put(Function<org.springframework.http.ResponseEntity<T>,org.springframework.http.ResponseEntity<S>> converter)
     
    sensitive(String... names)
    Sets the names of sensitive headers that are not passed downstream to the backend service.
    uri(String uri)
    Sets the uri for the backend call when triggered by the HTTP methods.
    uri(URI uri)
    Sets the uri for the backend call when triggered by the HTTP methods.

    Methods inherited from class java.lang.Object

    clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
  • Field Details

    • DEFAULT_SENSITIVE

      public static Set<String> DEFAULT_SENSITIVE
      Contains headers that are considered case-sensitive by default.
  • Constructor Details

    • ProxyExchange

      public ProxyExchange(org.springframework.web.client.RestTemplate rest, org.springframework.web.context.request.NativeWebRequest webRequest, org.springframework.web.method.support.ModelAndViewContainer mavContainer, org.springframework.web.bind.support.WebDataBinderFactory binderFactory, Type type)
  • Method Details

    • body

      public ProxyExchange<T> body(Object body)
      Sets the body for the downstream request (if using 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.
      Parameters:
      body - the request body to send downstream
      Returns:
      this for convenience
    • header

      public ProxyExchange<T> header(String name, String... value)
      Sets a header for the downstream call.
      Parameters:
      name - Header name
      value - Header values
      Returns:
      this for convenience
    • headers

      public ProxyExchange<T> headers(org.springframework.http.HttpHeaders 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

      public ProxyExchange<T> sensitive(String... names)
      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
    • uri

      public ProxyExchange<T> uri(URI 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
    • uri

      public ProxyExchange<T> uri(String 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

      public String path()
    • path

      public String path(String prefix)
    • forward

      public void forward(String path)
    • get

      public org.springframework.http.ResponseEntity<T> get()
    • get

      public <S> org.springframework.http.ResponseEntity<S> get(Function<org.springframework.http.ResponseEntity<T>,org.springframework.http.ResponseEntity<S>> converter)
    • head

      public org.springframework.http.ResponseEntity<T> head()
    • head

      public <S> org.springframework.http.ResponseEntity<S> head(Function<org.springframework.http.ResponseEntity<T>,org.springframework.http.ResponseEntity<S>> converter)
    • options

      public org.springframework.http.ResponseEntity<T> options()
    • options

      public <S> org.springframework.http.ResponseEntity<S> options(Function<org.springframework.http.ResponseEntity<T>,org.springframework.http.ResponseEntity<S>> converter)
    • post

      public org.springframework.http.ResponseEntity<T> post()
    • post

      public <S> org.springframework.http.ResponseEntity<S> post(Function<org.springframework.http.ResponseEntity<T>,org.springframework.http.ResponseEntity<S>> converter)
    • delete

      public org.springframework.http.ResponseEntity<T> delete()
    • delete

      public <S> org.springframework.http.ResponseEntity<S> delete(Function<org.springframework.http.ResponseEntity<T>,org.springframework.http.ResponseEntity<S>> converter)
    • put

      public org.springframework.http.ResponseEntity<T> put()
    • put

      public <S> org.springframework.http.ResponseEntity<S> put(Function<org.springframework.http.ResponseEntity<T>,org.springframework.http.ResponseEntity<S>> converter)
    • patch

      public org.springframework.http.ResponseEntity<T> patch()
    • patch

      public <S> org.springframework.http.ResponseEntity<S> patch(Function<org.springframework.http.ResponseEntity<T>,org.springframework.http.ResponseEntity<S>> converter)