Class 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
    • Field Summary

      Fields 
      Modifier and Type Field Description
      static Set<String> DEFAULT_SENSITIVE
      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

      All Methods Instance Methods Concrete Methods 
      Modifier and Type Method Description
      ProxyExchange<T> body​(Object body)
      Sets the body for the downstream request (if using post(), put() or patch()).
      org.springframework.http.ResponseEntity<T> delete()  
      <S> org.springframework.http.ResponseEntity<S> delete​(Function<org.springframework.http.ResponseEntity<T>,​org.springframework.http.ResponseEntity<S>> converter)  
      void forward​(String path)  
      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> head()  
      <S> 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.
      org.springframework.http.ResponseEntity<T> options()  
      <S> org.springframework.http.ResponseEntity<S> options​(Function<org.springframework.http.ResponseEntity<T>,​org.springframework.http.ResponseEntity<S>> converter)  
      org.springframework.http.ResponseEntity<T> patch()  
      <S> org.springframework.http.ResponseEntity<S> patch​(Function<org.springframework.http.ResponseEntity<T>,​org.springframework.http.ResponseEntity<S>> converter)  
      String path()  
      String path​(String prefix)  
      org.springframework.http.ResponseEntity<T> post()  
      <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)  
      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.
      ProxyExchange<T> uri​(URI uri)
      Sets the uri for the backend call when triggered by the HTTP methods.
    • Field Detail

      • DEFAULT_SENSITIVE

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

      • 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 Detail

      • 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
      • 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)