Class ProxyExchange<T>


  • public class ProxyExchange<T>
    extends java.lang.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 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).

    Author:
    Dave Syer
    • Field Summary

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

      Constructors 
      Constructor Description
      ProxyExchange​(org.springframework.web.reactive.function.client.WebClient rest, org.springframework.web.server.ServerWebExchange exchange, org.springframework.web.reactive.BindingContext bindingContext, java.lang.reflect.Type type)  
    • Method Summary

      All Methods Instance Methods Concrete Methods 
      Modifier and Type Method Description
      ProxyExchange<T> body​(java.lang.Object body)
      Sets the body for the downstream request (if using post(), put() or patch()).
      ProxyExchange<T> body​(org.reactivestreams.Publisher<?> body)
      Sets the body for the downstream request (if using post(), put() or patch()).
      reactor.core.publisher.Mono<org.springframework.http.ResponseEntity<T>> delete()  
      <S> reactor.core.publisher.Mono<org.springframework.http.ResponseEntity<S>> delete​(java.util.function.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​(java.util.function.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​(java.util.function.Function<org.springframework.http.ResponseEntity<T>,​org.springframework.http.ResponseEntity<S>> converter)  
      ProxyExchange<T> header​(java.lang.String name, java.lang.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​(java.util.function.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​(java.util.function.Function<org.springframework.http.ResponseEntity<T>,​org.springframework.http.ResponseEntity<S>> converter)  
      java.lang.String path()  
      java.lang.String path​(java.lang.String prefix)  
      reactor.core.publisher.Mono<org.springframework.http.ResponseEntity<T>> post()  
      <S> reactor.core.publisher.Mono<org.springframework.http.ResponseEntity<S>> post​(java.util.function.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​(java.util.function.Function<org.springframework.http.ResponseEntity<T>,​org.springframework.http.ResponseEntity<S>> converter)  
      ProxyExchange<T> sensitive​(java.lang.String... names)
      Sets the names of sensitive headers that are not passed downstream to the backend service.
      ProxyExchange<T> uri​(java.lang.String 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 Detail

      • DEFAULT_SENSITIVE

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

      • ProxyExchange

        public ProxyExchange​(org.springframework.web.reactive.function.client.WebClient rest,
                             org.springframework.web.server.ServerWebExchange exchange,
                             org.springframework.web.reactive.BindingContext bindingContext,
                             java.lang.reflect.Type type)
    • Method Detail

      • body

        public ProxyExchange<T> body​(java.lang.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
      • body

        public ProxyExchange<T> body​(org.reactivestreams.Publisher<?> 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​(java.lang.String name,
                                       java.lang.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​(java.lang.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​(java.lang.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 java.lang.String path()
      • path

        public java.lang.String path​(java.lang.String prefix)
      • get

        public reactor.core.publisher.Mono<org.springframework.http.ResponseEntity<T>> get()
      • get

        public <S> reactor.core.publisher.Mono<org.springframework.http.ResponseEntity<S>> get​(java.util.function.Function<org.springframework.http.ResponseEntity<T>,​org.springframework.http.ResponseEntity<S>> converter)
      • head

        public reactor.core.publisher.Mono<org.springframework.http.ResponseEntity<T>> head()
      • head

        public <S> reactor.core.publisher.Mono<org.springframework.http.ResponseEntity<S>> head​(java.util.function.Function<org.springframework.http.ResponseEntity<T>,​org.springframework.http.ResponseEntity<S>> converter)
      • options

        public reactor.core.publisher.Mono<org.springframework.http.ResponseEntity<T>> options()
      • options

        public <S> reactor.core.publisher.Mono<org.springframework.http.ResponseEntity<S>> options​(java.util.function.Function<org.springframework.http.ResponseEntity<T>,​org.springframework.http.ResponseEntity<S>> converter)
      • post

        public reactor.core.publisher.Mono<org.springframework.http.ResponseEntity<T>> post()
      • post

        public <S> reactor.core.publisher.Mono<org.springframework.http.ResponseEntity<S>> post​(java.util.function.Function<org.springframework.http.ResponseEntity<T>,​org.springframework.http.ResponseEntity<S>> converter)
      • delete

        public reactor.core.publisher.Mono<org.springframework.http.ResponseEntity<T>> delete()
      • delete

        public <S> reactor.core.publisher.Mono<org.springframework.http.ResponseEntity<S>> delete​(java.util.function.Function<org.springframework.http.ResponseEntity<T>,​org.springframework.http.ResponseEntity<S>> converter)
      • put

        public reactor.core.publisher.Mono<org.springframework.http.ResponseEntity<T>> put()
      • put

        public <S> reactor.core.publisher.Mono<org.springframework.http.ResponseEntity<S>> put​(java.util.function.Function<org.springframework.http.ResponseEntity<T>,​org.springframework.http.ResponseEntity<S>> converter)
      • patch

        public reactor.core.publisher.Mono<org.springframework.http.ResponseEntity<T>> patch()
      • patch

        public <S> reactor.core.publisher.Mono<org.springframework.http.ResponseEntity<S>> patch​(java.util.function.Function<org.springframework.http.ResponseEntity<T>,​org.springframework.http.ResponseEntity<S>> converter)