Initial documentation.
Includes general documentation and most filters. TODO: request predicates and custome dev docs.
This commit is contained in:
@@ -70,6 +70,44 @@
|
||||
** xref:spring-cloud-gateway-server-mvc/glossary.adoc[]
|
||||
** xref:spring-cloud-gateway-server-mvc/how-it-works.adoc[]
|
||||
** xref:spring-cloud-gateway-server-mvc/java-routes-api.adoc[]
|
||||
** xref:spring-cloud-gateway-server-mvc/gateway-request-predicates.adoc[]
|
||||
** xref:spring-cloud-gateway-server-mvc/gateway-handler-filter-functions.adoc[]
|
||||
*** xref:spring-cloud-gateway-server-mvc/filters/addrequestheader.adoc[]
|
||||
*** xref:spring-cloud-gateway-server-mvc/filters/addrequestheadersifnotpresent.adoc[]
|
||||
*** xref:spring-cloud-gateway-server-mvc/filters/addrequestparameter.adoc[]
|
||||
*** xref:spring-cloud-gateway-server-mvc/filters/addresponseheader.adoc[]
|
||||
*** xref:spring-cloud-gateway-server-mvc/filters/circuitbreaker-filter.adoc[]
|
||||
*** xref:spring-cloud-gateway-server-mvc/filters/deduperesponseheader.adoc[]
|
||||
*** xref:spring-cloud-gateway-server-mvc/filters/fallback-headers.adoc[]
|
||||
//*** xref:spring-cloud-gateway-server-mvc/filters/local-cache-response-filter.adoc[]
|
||||
*** xref:spring-cloud-gateway-server-mvc/filters/maprequestheader.adoc[]
|
||||
*** xref:spring-cloud-gateway-server-mvc/filters/modifyrequestbody.adoc[]
|
||||
//*** xref:spring-cloud-gateway-server-mvc/filters/modifyresponsebody.adoc[]
|
||||
*** xref:spring-cloud-gateway-server-mvc/filters/prefixpath.adoc[]
|
||||
*** xref:spring-cloud-gateway-server-mvc/filters/preservehostheader.adoc[]
|
||||
*** xref:spring-cloud-gateway-server-mvc/filters/redirectto.adoc[]
|
||||
//*** xref:spring-cloud-gateway-server-mvc/filters/removejsonattributesresponsebody.adoc[]
|
||||
*** xref:spring-cloud-gateway-server-mvc/filters/removerequestheader.adoc[]
|
||||
*** xref:spring-cloud-gateway-server-mvc/filters/removerequestparameter.adoc[]
|
||||
*** xref:spring-cloud-gateway-server-mvc/filters/removeresponseheader.adoc[]
|
||||
*** xref:spring-cloud-gateway-server-mvc/filters/requestheadersize.adoc[]
|
||||
*** xref:spring-cloud-gateway-server-mvc/filters/requestratelimiter.adoc[]
|
||||
*** xref:spring-cloud-gateway-server-mvc/filters/rewritelocationresponseheader.adoc[]
|
||||
*** xref:spring-cloud-gateway-server-mvc/filters/rewritepath.adoc[]
|
||||
//*** xref:spring-cloud-gateway-server-mvc/filters/rewriterequestparameter.adoc[]
|
||||
*** xref:spring-cloud-gateway-server-mvc/filters/rewriteresponseheader.adoc[]
|
||||
//*** xref:spring-cloud-gateway-server-mvc/filters/savesession.adoc[]
|
||||
//*** xref:spring-cloud-gateway-server-mvc/filters/secureheaders.adoc[]
|
||||
*** xref:spring-cloud-gateway-server-mvc/filters/setpath.adoc[]
|
||||
*** xref:spring-cloud-gateway-server-mvc/filters/setrequestheader.adoc[]
|
||||
*** xref:spring-cloud-gateway-server-mvc/filters/setresponseheader.adoc[]
|
||||
*** xref:spring-cloud-gateway-server-mvc/filters/setstatus.adoc[]
|
||||
*** xref:spring-cloud-gateway-server-mvc/filters/stripprefix.adoc[]
|
||||
*** xref:spring-cloud-gateway-server-mvc/filters/retry.adoc[]
|
||||
*** xref:spring-cloud-gateway-server-mvc/filters/requestsize.adoc[]
|
||||
*** xref:spring-cloud-gateway-server-mvc/filters/setrequesthostheader.adoc[]
|
||||
*** xref:spring-cloud-gateway-server-mvc/filters/tokenrelay.adoc[]
|
||||
** xref:spring-cloud-gateway-server-mvc/writing-custom-predicates-and-filters.adoc[]
|
||||
|
||||
// begin Gateway Proxy Exchange
|
||||
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
[[addrequestheader-filter]]
|
||||
= `AddRequestHeader` Filter
|
||||
|
||||
The `AddRequestHeader` is a "before" filter that takes a `name` and `value` parameter.
|
||||
The following example configures an `AddRequestHeader` filter:
|
||||
|
||||
.GatewaySampleApplication.java
|
||||
[source,java]
|
||||
----
|
||||
import static org.springframework.cloud.gateway.server.mvc.filter.BeforeFilterFunctions.addRequestHeader;
|
||||
import static org.springframework.cloud.gateway.server.mvc.handler.GatewayRouterFunctions.route;
|
||||
import static org.springframework.cloud.gateway.server.mvc.handler.HandlerFunctions.http;
|
||||
|
||||
@Configuration
|
||||
class RouteConfiguration {
|
||||
|
||||
@Bean
|
||||
public RouterFunction<ServerResponse> gatewayRouterFunctionsAddReqHeader() {
|
||||
return route(GET("/red"), http("https://example.org"))
|
||||
.before(addRequestHeader("X-Request-red", "blue"));
|
||||
}
|
||||
}
|
||||
----
|
||||
|
||||
This listing adds `X-Request-red:blue` header to the downstream request's headers for all matching requests.
|
||||
|
||||
`AddRequestHeader` is aware of the URI variables used to match a path or host.
|
||||
URI variables may be used in the value and are expanded at runtime.
|
||||
The following example configures an `AddRequestHeader` filter that uses a variable:
|
||||
|
||||
.GatewaySampleApplication.java
|
||||
[source,java]
|
||||
----
|
||||
@Configuration
|
||||
class RouteConfiguration {
|
||||
|
||||
@Bean
|
||||
public RouterFunction<ServerResponse> gatewayRouterFunctionsAddReqHeader() {
|
||||
return route(GET("/red/{segment}"), http("https://example.org"))
|
||||
.before(addRequestHeader("X-Request-red", "blue-{segment}"));
|
||||
}
|
||||
}
|
||||
----
|
||||
@@ -0,0 +1,62 @@
|
||||
[[addrequestheadersifnotpresent-filter]]
|
||||
= `AddRequestHeadersIfNotPresent` Filter
|
||||
|
||||
The `AddRequestHeadersIfNotPresent` filter takes a collection of `name` and `value` pairs separated by colon.
|
||||
The following example configures an `AddRequestHeadersIfNotPresent` filter:
|
||||
|
||||
.GatewaySampleApplication.java
|
||||
[source,java]
|
||||
----
|
||||
import static org.springframework.cloud.gateway.server.mvc.filter.BeforeFilterFunctions.addRequestHeadersIfNotPresent;
|
||||
import static org.springframework.cloud.gateway.server.mvc.handler.GatewayRouterFunctions.route;
|
||||
import static org.springframework.cloud.gateway.server.mvc.handler.HandlerFunctions.http;
|
||||
|
||||
@Configuration
|
||||
class RouteConfiguration {
|
||||
|
||||
@Bean
|
||||
public RouterFunction<ServerResponse> gatewayRouterFunctionsAddReqHeader() {
|
||||
return route(GET("/red"), http("https://example.org"))
|
||||
.before(addRequestHeadersIfNotPresent("X-Request-Color-1:blue","X-Request-Color-2:green"));
|
||||
}
|
||||
}
|
||||
----
|
||||
|
||||
This listing adds 2 headers `X-Request-Color-1:blue` and `X-Request-Color-2:green` to the downstream request's headers for all matching requests.
|
||||
This is similar to how `AddRequestHeader` works, but unlike `AddRequestHeader` it will do it only if the header is not already there.
|
||||
Otherwise, the original value in the client request is sent.
|
||||
|
||||
Additionally, to set a multi-valued header, use the header name multiple times like `addRequestHeadersIfNotPresent("X-Request-Color-1:blue","X-Request-Color-1:green")`.
|
||||
|
||||
`AddRequestHeadersIfNotPresent` also supports URI variables used to match a path or host.
|
||||
URI variables may be used in the value and are expanded at runtime.
|
||||
The following example configures an `AddRequestHeadersIfNotPresent` filter that uses a variable:
|
||||
|
||||
.GatewaySampleApplication.java
|
||||
[source,java]
|
||||
----
|
||||
@Configuration
|
||||
class RouteConfiguration {
|
||||
|
||||
@Bean
|
||||
public RouterFunction<ServerResponse> gatewayRouterFunctionsAddReqHeader() {
|
||||
return route(GET("/red/{segment}"), http("https://example.org"))
|
||||
.before(addRequestHeadersIfNotPresent("X-Request-red", "blue-{segment}"));
|
||||
}
|
||||
}
|
||||
----
|
||||
.application.yml
|
||||
[source,yaml]
|
||||
----
|
||||
spring:
|
||||
cloud:
|
||||
gateway:
|
||||
routes:
|
||||
- id: add_request_header_route
|
||||
uri: https://example.org
|
||||
predicates:
|
||||
- Path=/red/{segment}
|
||||
filters:
|
||||
- AddRequestHeadersIfNotPresent=X-Request-Red:Blue-{segment}
|
||||
----
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
[[addrequestparameter-filter]]
|
||||
= `AddRequestParameter` Filter
|
||||
|
||||
The `AddRequestParameter` Filter takes a `name` and `value` parameter.
|
||||
The following example configures an `AddRequestParameter` filter:
|
||||
|
||||
.GatewaySampleApplication.java
|
||||
[source,java]
|
||||
----
|
||||
import static org.springframework.cloud.gateway.server.mvc.filter.BeforeFilterFunctions.addRequestParameter;
|
||||
import static org.springframework.cloud.gateway.server.mvc.handler.GatewayRouterFunctions.route;
|
||||
import static org.springframework.cloud.gateway.server.mvc.handler.HandlerFunctions.http;
|
||||
|
||||
@Configuration
|
||||
class RouteConfiguration {
|
||||
|
||||
@Bean
|
||||
public RouterFunction<ServerResponse> gatewayRouterFunctionsAddReqHeader() {
|
||||
return route("add_request_parameter_route")
|
||||
.GET("/anything/addrequestparam", http("https://example.org"))
|
||||
.before(addRequestParameter("red", "blue"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
----
|
||||
|
||||
This will add `red=blue` to the downstream request's query string for all matching requests.
|
||||
|
||||
`AddRequestParameter` is aware of the URI variables used to match a path or host.
|
||||
URI variables may be used in the value and are expanded at runtime.
|
||||
The following example configures an `AddRequestParameter` filter that uses a variable:
|
||||
|
||||
.GatewaySampleApplication.java
|
||||
[source,java]
|
||||
----
|
||||
import static org.springframework.cloud.gateway.server.mvc.filter.BeforeFilterFunctions.addRequestParameter;
|
||||
import static org.springframework.cloud.gateway.server.mvc.handler.GatewayRouterFunctions.route;
|
||||
import static org.springframework.cloud.gateway.server.mvc.handler.HandlerFunctions.http;
|
||||
import static org.springframework.cloud.gateway.server.mvc.predicate.GatewayRequestPredicates.host;
|
||||
|
||||
@Configuration
|
||||
class RouteConfiguration {
|
||||
|
||||
@Bean
|
||||
public RouterFunction<ServerResponse> gatewayRouterFunctionsAddReqHeader() {
|
||||
return route("add_request_parameter_route")
|
||||
.route(host("{segment}.myhost.org"), http("https://example.org"))
|
||||
.before(addRequestParameter("foo", "bar-{segment}"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
----
|
||||
@@ -0,0 +1,53 @@
|
||||
[[addresponseheader-filter]]
|
||||
= `AddResponseHeader` Filter
|
||||
|
||||
The `AddResponseHeader` Filter takes a `name` and `value` parameter.
|
||||
The following example configures an `AddResponseHeader` filter:
|
||||
|
||||
.GatewaySampleApplication.java
|
||||
[source,java]
|
||||
----
|
||||
import static org.springframework.cloud.gateway.server.mvc.filter.AfterFilterFunctions.addResponseHeader;
|
||||
import static org.springframework.cloud.gateway.server.mvc.handler.GatewayRouterFunctions.route;
|
||||
import static org.springframework.cloud.gateway.server.mvc.handler.HandlerFunctions.http;
|
||||
|
||||
@Configuration
|
||||
class RouteConfiguration {
|
||||
|
||||
@Bean
|
||||
public RouterFunction<ServerResponse> gatewayRouterFunctionsAddRespHeader() {
|
||||
return route("addresponseheader")
|
||||
.GET("/anything/addresheader", http("https://example.org"))
|
||||
.after(addResponseHeader("X-Response-Red", "Blue"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
----
|
||||
|
||||
This adds `X-Response-Red:Blue` header to the downstream response's headers for all matching requests.
|
||||
|
||||
`AddResponseHeader` is aware of URI variables used to match a path or host.
|
||||
URI variables may be used in the value and are expanded at runtime.
|
||||
The following example configures an `AddResponseHeader` filter that uses a variable:
|
||||
|
||||
.GatewaySampleApplication.java
|
||||
[source,java]
|
||||
----
|
||||
import static org.springframework.cloud.gateway.server.mvc.filter.AfterFilterFunctions.addResponseHeader;
|
||||
import static org.springframework.cloud.gateway.server.mvc.handler.GatewayRouterFunctions.route;
|
||||
import static org.springframework.cloud.gateway.server.mvc.handler.HandlerFunctions.http;
|
||||
import static org.springframework.cloud.gateway.server.mvc.predicate.GatewayRequestPredicates.host;
|
||||
|
||||
@Configuration
|
||||
class RouteConfiguration {
|
||||
|
||||
@Bean
|
||||
public RouterFunction<ServerResponse> gatewayRouterFunctionsAddRespHeader() {
|
||||
return route("add_response_header_route")
|
||||
.route(host("{segment}.myhost.org"), http("https://example.org"))
|
||||
.after(addResponseHeader("foo", "bar-{segment}"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
----
|
||||
|
||||
@@ -0,0 +1,210 @@
|
||||
[[spring-cloud-circuitbreaker-filter-factory]]
|
||||
= `CircuitBreaker` Filter
|
||||
|
||||
The Spring Cloud CircuitBreaker GatewayFilter factory uses the Spring Cloud CircuitBreaker APIs to wrap Gateway routes in
|
||||
a circuit breaker. Spring Cloud CircuitBreaker supports multiple libraries that can be used with Spring Cloud Gateway. Spring Cloud supports Resilience4J out of the box.
|
||||
|
||||
To enable the Spring Cloud CircuitBreaker filter, you need to place `spring-cloud-starter-circuitbreaker-reactor-resilience4j` on the classpath.
|
||||
The following example configures a Spring Cloud CircuitBreaker filter:
|
||||
|
||||
.application.yml
|
||||
[source,yaml]
|
||||
----
|
||||
spring:
|
||||
cloud:
|
||||
gateway:
|
||||
routes:
|
||||
- id: circuitbreaker_route
|
||||
uri: https://example.org
|
||||
filters:
|
||||
- CircuitBreaker=myCircuitBreaker
|
||||
----
|
||||
.GatewaySampleApplication.java
|
||||
[source,java]
|
||||
----
|
||||
import static org.springframework.cloud.gateway.server.mvc.filter.CircuitBreakerFilterFunctions.circuitBreaker;
|
||||
import static org.springframework.cloud.gateway.server.mvc.handler.GatewayRouterFunctions.route;
|
||||
import static org.springframework.cloud.gateway.server.mvc.handler.HandlerFunctions.http;
|
||||
|
||||
@Configuration
|
||||
class RouteConfiguration {
|
||||
|
||||
@Bean
|
||||
public RouterFunction<ServerResponse> gatewayRouterFunctionsCircuitBreakerNoFallback() {
|
||||
return route("circuitbreakernofallback")
|
||||
.route(path("/anything/circuitbreakernofallback"), http("https://example.org"))
|
||||
.filter(circuitBreaker("mycb3"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
----
|
||||
|
||||
To configure the circuit breaker, see the configuration for the underlying circuit breaker implementation you are using.
|
||||
|
||||
* https://cloud.spring.io/spring-cloud-circuitbreaker/reference/html/spring-cloud-circuitbreaker.html[Resilience4J Documentation]
|
||||
|
||||
The Spring Cloud CircuitBreaker filter can also accept an optional `fallbackUri` parameter.
|
||||
Currently, only `forward:` schemed URIs are supported.
|
||||
If the fallback is called, the request is forwarded to the controller matched by the URI.
|
||||
The following example configures such a fallback:
|
||||
|
||||
.application.yml
|
||||
[source,yaml]
|
||||
----
|
||||
spring:
|
||||
cloud:
|
||||
gateway:
|
||||
routes:
|
||||
- id: circuitbreaker_route
|
||||
uri: https://example.org
|
||||
predicates:
|
||||
- Path=/consumingServiceEndpoint
|
||||
filters:
|
||||
- name: CircuitBreaker
|
||||
args:
|
||||
name: myCircuitBreaker
|
||||
fallbackUri: forward:/inCaseOfFailureUseThis
|
||||
----
|
||||
|
||||
The following listing does the same thing in Java:
|
||||
|
||||
.GatewaySampleApplication.java
|
||||
[source,java]
|
||||
----
|
||||
import java.net.URI;
|
||||
import static org.springframework.cloud.gateway.server.mvc.filter.CircuitBreakerFilterFunctions.circuitBreaker;
|
||||
import static org.springframework.cloud.gateway.server.mvc.handler.GatewayRouterFunctions.route;
|
||||
import static org.springframework.cloud.gateway.server.mvc.handler.HandlerFunctions.http;
|
||||
|
||||
@Configuration
|
||||
class RouteConfiguration {
|
||||
|
||||
@Bean
|
||||
public RouterFunction<ServerResponse> gatewayRouterFunctionsCircuitBreakerFallback() {
|
||||
return route("circuitbreaker_route")
|
||||
.route(path("/consumingServiceEndpoint"), http("https://example.org"))
|
||||
.filter(circuitBreaker("myCircuitBreaker", URI.create("forward:/inCaseOfFailureUseThis")))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
----
|
||||
|
||||
This example forwards to the `/inCaseofFailureUseThis` URI when the circuit breaker fallback is called.
|
||||
|
||||
CircuitBreaker also supports URI variables in the `fallbackUri`.
|
||||
This allows more complex routing options, like forwarding sections of the original host or url path using https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/util/pattern/PathPattern.html[PathPattern expression].
|
||||
|
||||
In the example below the call `consumingServiceEndpoint/users/1` will be redirected to `inCaseOfFailureUseThis/users/1`.
|
||||
|
||||
.GatewaySampleApplication.java
|
||||
[source,java]
|
||||
----
|
||||
import java.net.URI;
|
||||
import static org.springframework.cloud.gateway.server.mvc.filter.CircuitBreakerFilterFunctions.circuitBreaker;
|
||||
import static org.springframework.cloud.gateway.server.mvc.handler.GatewayRouterFunctions.route;
|
||||
import static org.springframework.cloud.gateway.server.mvc.handler.HandlerFunctions.http;
|
||||
|
||||
@Configuration
|
||||
class RouteConfiguration {
|
||||
|
||||
@Bean
|
||||
public RouterFunction<ServerResponse> gatewayRouterFunctionsCircuitBreakerFallback() {
|
||||
return route("circuitbreaker_route")
|
||||
.route(path("/consumingServiceEndpoint/{*segments}"), http("https://example.org"))
|
||||
.filter(circuitBreaker("myCircuitBreaker", URI.create("forward:/inCaseOfFailureUseThis/{segments}")))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
----
|
||||
|
||||
|
||||
The primary scenario is to use the `fallbackUri` to define an internal controller or handler within the gateway application.
|
||||
However, you can also reroute the request to a controller or handler in an external application, as follows:
|
||||
|
||||
.GatewaySampleApplication.java
|
||||
[source,java]
|
||||
----
|
||||
import static org.springframework.cloud.gateway.server.mvc.filter.CircuitBreakerFilterFunctions.circuitBreaker;
|
||||
import static org.springframework.cloud.gateway.server.mvc.filter.LoadBalancerFilterFunctions.lb;
|
||||
import static org.springframework.cloud.gateway.server.mvc.handler.GatewayRouterFunctions.route;
|
||||
import static org.springframework.cloud.gateway.server.mvc.handler.HandlerFunctions.http;
|
||||
|
||||
@Configuration
|
||||
class RouteConfiguration {
|
||||
|
||||
@Bean
|
||||
public RouterFunction<ServerResponse> gatewayRouterFunctionsCircuitBreakerFallbackToGatewayRoute() {
|
||||
return route("ingredients")
|
||||
.route(path("/ingredients/**"), http())
|
||||
.filter(lb("ingredients"))
|
||||
.filter(circuitBreaker("fetchIngredients", URI.create("forward:/fallback")))
|
||||
.build()
|
||||
.and(route("ingredients-fallback")
|
||||
.route(path("/fallback"), http("http://localhost:9994"))
|
||||
.build());
|
||||
}
|
||||
}
|
||||
----
|
||||
|
||||
In this example, there is no `fallback` endpoint or handler in the gateway application.
|
||||
However, there is one in another application, registered under `http://localhost:9994`.
|
||||
|
||||
In case of the request being forwarded to fallback, the Spring Cloud CircuitBreaker Gateway filter also provides the `Throwable` that has caused it.
|
||||
It is added to the `ServerRequest` as the `MvcUtils.CIRCUITBREAKER_EXECUTION_EXCEPTION_ATTR` attribute that can be used when handling the fallback within the gateway application.
|
||||
|
||||
For the external controller/handler scenario, headers can be added with exception details.
|
||||
You can find more information on doing so in the xref:spring-cloud-gateway-server-mvc/filters/fallback-headers.adoc[FallbackHeaders Filters section].
|
||||
|
||||
[[circuit-breaker-status-codes]]
|
||||
== Tripping The Circuit Breaker On Status Codes
|
||||
|
||||
In some cases you might want to trip a circuit breaker based on the status code
|
||||
returned from the route it wraps. The circuit breaker config object takes a list of
|
||||
status codes that if returned will cause the circuit breaker to be tripped. When setting the
|
||||
status codes you want to trip the circuit breaker you can either use an integer with the status code
|
||||
value or the String representation of the `HttpStatus` enumeration.
|
||||
|
||||
.application.yml
|
||||
[source,yaml]
|
||||
----
|
||||
spring:
|
||||
cloud:
|
||||
gateway:
|
||||
routes:
|
||||
- id: circuitbreaker_route
|
||||
uri: lb://backing-service:8088
|
||||
predicates:
|
||||
- Path=/consumingServiceEndpoint
|
||||
filters:
|
||||
- name: CircuitBreaker
|
||||
args:
|
||||
name: myCircuitBreaker
|
||||
fallbackUri: forward:/inCaseOfFailureUseThis
|
||||
statusCodes:
|
||||
- 500
|
||||
- "NOT_FOUND"
|
||||
----
|
||||
|
||||
.GatewaySampleApplication.java
|
||||
[source,java]
|
||||
----
|
||||
import java.net.URI;
|
||||
import static org.springframework.cloud.gateway.server.mvc.filter.CircuitBreakerFilterFunctions.circuitBreaker;
|
||||
import static org.springframework.cloud.gateway.server.mvc.filter.LoadBalancerFilterFunctions.lb;
|
||||
import static org.springframework.cloud.gateway.server.mvc.handler.GatewayRouterFunctions.route;
|
||||
import static org.springframework.cloud.gateway.server.mvc.handler.HandlerFunctions.http;
|
||||
|
||||
@Configuration
|
||||
class RouteConfiguration {
|
||||
|
||||
@Bean
|
||||
public RouterFunction<ServerResponse> gatewayRouterFunctionsCircuitBreakerFallback() {
|
||||
return route("circuitbreaker_route")
|
||||
.route(path("/consumingServiceEndpoint"), http())
|
||||
.filter(lb("backing-service"))
|
||||
.filter(circuitBreaker(config -> config.setId("myCircuitBreaker").setFallbackUri("forward:/inCaseOfFailureUseThis").setStatusCodes("500", "NOT_FOUND")))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
----
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
[[deduperesponseheader-filter]]
|
||||
= `DedupeResponseHeader` Filter
|
||||
|
||||
The `DedupeResponseHeader` GatewayFilter factory takes a `name` parameter and an optional `strategy` parameter. `name` can contain a space-separated list of header names.
|
||||
The following example configures a `DedupeResponseHeader` filter:
|
||||
|
||||
.application.yml
|
||||
[source,yaml]
|
||||
----
|
||||
spring:
|
||||
cloud:
|
||||
gateway:
|
||||
routes:
|
||||
- id: dedupe_response_header_route
|
||||
uri: https://example.org
|
||||
filters:
|
||||
- DedupeResponseHeader=Access-Control-Allow-Credentials Access-Control-Allow-Origin
|
||||
----
|
||||
.GatewaySampleApplication.java
|
||||
[source,java]
|
||||
----
|
||||
import static org.springframework.cloud.gateway.server.mvc.filter.AfterFilterFunctions.dedupeResponseHeader;
|
||||
import static org.springframework.cloud.gateway.server.mvc.handler.GatewayRouterFunctions.route;
|
||||
import static org.springframework.cloud.gateway.server.mvc.handler.HandlerFunctions.http;
|
||||
import static org.springframework.web.servlet.function.RequestPredicates.path;
|
||||
|
||||
|
||||
@Configuration
|
||||
class RouteConfiguration {
|
||||
|
||||
@Bean
|
||||
public RouterFunction<ServerResponse> gatewayRouterFunctionsDedupeResponseHeader() {
|
||||
return route("dedupe_response_header_route")
|
||||
.route(path("/hello"), http("https://example.org"))
|
||||
.after(dedupeResponseHeader("Access-Control-Allow-Credentials Access-Control-Allow-Origin"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
----
|
||||
|
||||
This removes duplicate values of `Access-Control-Allow-Credentials` and `Access-Control-Allow-Origin` response headers in cases when both the gateway CORS logic and the downstream logic add them.
|
||||
|
||||
The `DedupeResponseHeader` filter also accepts an optional `strategy` parameter.
|
||||
The accepted values are `RETAIN_FIRST` (default), `RETAIN_LAST`, and `RETAIN_UNIQUE`.
|
||||
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
[[fallback-headers]]
|
||||
= `FallbackHeaders` Filter
|
||||
|
||||
The `FallbackHeaders` factory lets you add Spring Cloud CircuitBreaker execution exception details in the headers of a request forwarded to a `fallbackUri` in an external application, as in the following scenario:
|
||||
|
||||
.application.yml
|
||||
[source,yaml]
|
||||
----
|
||||
spring:
|
||||
cloud:
|
||||
gateway:
|
||||
routes:
|
||||
- id: ingredients
|
||||
uri: lb://ingredients
|
||||
predicates:
|
||||
- Path=//ingredients/**
|
||||
filters:
|
||||
- name: CircuitBreaker
|
||||
args:
|
||||
name: fetchIngredients
|
||||
fallbackUri: forward:/fallback
|
||||
- id: ingredients-fallback
|
||||
uri: http://localhost:9994
|
||||
predicates:
|
||||
- Path=/fallback
|
||||
filters:
|
||||
- name: FallbackHeaders
|
||||
args:
|
||||
executionExceptionTypeHeaderName: Test-Header
|
||||
----
|
||||
|
||||
.GatewaySampleApplication.java
|
||||
[source,java]
|
||||
----
|
||||
import static org.springframework.cloud.gateway.server.mvc.filter.CircuitBreakerFilterFunctions.circuitBreaker;
|
||||
import static org.springframework.cloud.gateway.server.mvc.filter.BeforeFilterFunctions.fallbackHeaders;
|
||||
import static org.springframework.cloud.gateway.server.mvc.filter.LoadBalancerFilterFunctions.lb;
|
||||
import static org.springframework.cloud.gateway.server.mvc.handler.GatewayRouterFunctions.route;
|
||||
import static org.springframework.cloud.gateway.server.mvc.handler.HandlerFunctions.http;
|
||||
|
||||
@Configuration
|
||||
class RouteConfiguration {
|
||||
|
||||
@Bean
|
||||
public RouterFunction<ServerResponse> gatewayRouterFunctionsCircuitBreakerFallbackToGatewayRoute() {
|
||||
return route("ingredients")
|
||||
.route(path("/ingredients/**"), http())
|
||||
.filter(lb("ingredients"))
|
||||
.filter(circuitBreaker("fetchIngredients", URI.create("forward:/fallback")))
|
||||
.build()
|
||||
.and(route("ingredients-fallback")
|
||||
.route(path("/fallback"), http("http://localhost:9994"))
|
||||
.before(fallbackHeaders())
|
||||
.build());
|
||||
}
|
||||
}
|
||||
----
|
||||
|
||||
In this example, after an execution exception occurs while running the circuit breaker, the request is forwarded to the `fallback` endpoint or handler in an application running on `localhost:9994`.
|
||||
The headers with the exception type, message and (if available) root cause exception type and message are added to that request by the `FallbackHeaders` filter.
|
||||
|
||||
You can overwrite the names of the headers in the configuration by setting the values of the following arguments (shown with their default values):
|
||||
|
||||
* `executionExceptionTypeHeaderName` (`"Execution-Exception-Type"`)
|
||||
* `executionExceptionMessageHeaderName` (`"Execution-Exception-Message"`)
|
||||
* `rootCauseExceptionTypeHeaderName` (`"Root-Cause-Exception-Type"`)
|
||||
* `rootCauseExceptionMessageHeaderName` (`"Root-Cause-Exception-Message"`)
|
||||
|
||||
For more information on circuit breakers and the gateway see the xref:spring-cloud-gateway-server-mvc/filters/circuitbreaker-filter.adoc[Spring Cloud CircuitBreaker Filter section].
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
[[local-cache-response-filter]]
|
||||
= `LocalResponseCache` Filter
|
||||
|
||||
This filter allows caching the response body and headers to follow these rules:
|
||||
|
||||
* It can only cache bodiless GET requests.
|
||||
* It caches the response only for one of the following status codes: HTTP 200 (OK), HTTP 206 (Partial Content), or HTTP 301 (Moved Permanently).
|
||||
* Response data is not cached if `Cache-Control` header does not allow it (`no-store` present in the request or `no-store` or `private` present in the response).
|
||||
* If the response is already cached and a new request is performed with no-cache value in `Cache-Control` header, it returns a bodiless response with 304 (Not Modified).
|
||||
|
||||
This filter configures the local response cache per route and is available only if the `spring.cloud.gateway.filter.local-response-cache.enabled` property is enabled. And a xref:spring-cloud-gateway/global-filters.adoc#local-cache-response-global-filter[local response cache configured globally] is also available as feature.
|
||||
|
||||
It accepts the first parameter to override the time to expire a cache entry (expressed in `s` for seconds, `m` for minutes, and `h` for hours) and a second parameter to set the maximum size of the cache to evict entries for this route (`KB`, `MB`, or `GB`).
|
||||
|
||||
The following listing shows how to add local response cache filter:
|
||||
|
||||
[source,java]
|
||||
----
|
||||
@Bean
|
||||
public RouteLocator routes(RouteLocatorBuilder builder) {
|
||||
return builder.routes()
|
||||
.route("rewrite_response_upper", r -> r.host("*.rewriteresponseupper.org")
|
||||
.filters(f -> f.prefixPath("/httpbin")
|
||||
.localResponseCache(Duration.ofMinutes(30), "500MB")
|
||||
).uri(uri))
|
||||
.build();
|
||||
}
|
||||
----
|
||||
|
||||
or this
|
||||
|
||||
.application.yaml
|
||||
[source,yaml]
|
||||
----
|
||||
spring:
|
||||
cloud:
|
||||
gateway:
|
||||
routes:
|
||||
- id: resource
|
||||
uri: http://localhost:9000
|
||||
predicates:
|
||||
- Path=/resource
|
||||
filters:
|
||||
- LocalResponseCache=30m,500MB
|
||||
----
|
||||
|
||||
NOTE: This filter also automatically calculates the `max-age` value in the HTTP `Cache-Control` header.
|
||||
Only if `max-age` is present on the original response is the value rewritten with the number of seconds set in the `timeToLive` configuration parameter.
|
||||
In consecutive calls, this value is recalculated with the number of seconds left until the response expires.
|
||||
|
||||
NOTE: To enable this feature, add `com.github.ben-manes.caffeine:caffeine` and `spring-boot-starter-cache` as project dependencies.
|
||||
|
||||
WARNING: If your project creates custom `CacheManager` beans, it will either need to be marked with `@Primary` or injected using `@Qualifier`.
|
||||
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
[[maprequestheader-filter]]
|
||||
= `MapRequestHeader` Filter
|
||||
|
||||
The `MapRequestHeader` filter takes `fromHeader` and `toHeader` parameters.
|
||||
It creates a new named header (`toHeader`), and the value is extracted out of an existing named header (`fromHeader`) from the incoming http request.
|
||||
If the input header does not exist, the filter has no impact.
|
||||
If the new named header already exists, its values are augmented with the new values.
|
||||
The following example configures a `MapRequestHeader`:
|
||||
|
||||
.GatewaySampleApplication.java
|
||||
[source,java]
|
||||
----
|
||||
import static org.springframework.cloud.gateway.server.mvc.filter.BeforeFilterFunctions.addRequestParameter;
|
||||
import static org.springframework.cloud.gateway.server.mvc.handler.GatewayRouterFunctions.route;
|
||||
import static org.springframework.cloud.gateway.server.mvc.handler.HandlerFunctions.http;
|
||||
|
||||
@Configuration
|
||||
class RouteConfiguration {
|
||||
|
||||
@Bean
|
||||
public RouterFunction<ServerResponse> gatewayRouterFunctionsMapRequestHeader() {
|
||||
return route("map_request_header_route")
|
||||
.GET("/mypath", http("https://example.org"))
|
||||
.before(mapRequestHeader("Blue", "X-Request-Red"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
----
|
||||
|
||||
This adds the `X-Request-Red:<values>` header to the downstream request with updated values from the incoming HTTP request's `Blue` header.
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
[[modifyrequestbody-filter]]
|
||||
= `ModifyRequestBody` Filter
|
||||
|
||||
You can use the `ModifyRequestBody` filter to modify the request body before it is sent downstream by the gateway.
|
||||
|
||||
NOTE: This filter can be configured only by using the Java DSL.
|
||||
|
||||
The following listing shows how to modify a request body filter:
|
||||
|
||||
.GatewaySampleApplication.java
|
||||
[source,java]
|
||||
----
|
||||
import static org.springframework.cloud.gateway.server.mvc.filter.BeforeFilterFunctions.modifyRequestBody;
|
||||
import static org.springframework.cloud.gateway.server.mvc.handler.GatewayRouterFunctions.route;
|
||||
import static org.springframework.cloud.gateway.server.mvc.handler.HandlerFunctions.http;
|
||||
import static org.springframework.cloud.gateway.server.mvc.predicate.GatewayRequestPredicates.host;
|
||||
import org.springframework.http.MediaType;
|
||||
|
||||
@Configuration
|
||||
class RouteConfiguration {
|
||||
|
||||
@Bean
|
||||
public RouterFunction<ServerResponse> gatewayRouterFunctionsAddReqHeader() {
|
||||
return route("rewrite_request_obj")
|
||||
.route(host("*.rewriterequestobj.org"), http("https://example.org"))
|
||||
.before(modifyRequestBody(String.class, Hello.class, MediaType.APPLICATION_JSON_VALUE,
|
||||
(request, s) -> new Hello(s.toUpperCase())))
|
||||
.build();
|
||||
}
|
||||
|
||||
record Hello(String message) { }
|
||||
}
|
||||
----
|
||||
|
||||
NOTE: If the request has no body, the `RewriteFilter` is passed `null`. `Mono.empty()` should be returned to assign a missing body in the request.
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
[[modifyresponsebody-filter]]
|
||||
= `ModifyResponseBody` Filter
|
||||
|
||||
You can use the `ModifyResponseBody` filter to modify the response body before it is sent back to the client.
|
||||
|
||||
NOTE: This filter can be configured only by using the Java DSL.
|
||||
|
||||
The following listing shows how to modify a response body filter:
|
||||
|
||||
[source,java]
|
||||
----
|
||||
@Bean
|
||||
public RouteLocator routes(RouteLocatorBuilder builder) {
|
||||
return builder.routes()
|
||||
.route("rewrite_response_upper", r -> r.host("*.rewriteresponseupper.org")
|
||||
.filters(f -> f.prefixPath("/httpbin")
|
||||
.modifyResponseBody(String.class, String.class,
|
||||
(exchange, s) -> Mono.just(s.toUpperCase()))).uri(uri))
|
||||
.build();
|
||||
}
|
||||
----
|
||||
.GatewaySampleApplication.java
|
||||
[source,java]
|
||||
----
|
||||
import static org.springframework.cloud.gateway.server.mvc.filter.AfterFilterFunctions.modifyResponseBody;
|
||||
import static org.springframework.cloud.gateway.server.mvc.handler.GatewayRouterFunctions.route;
|
||||
import static org.springframework.cloud.gateway.server.mvc.handler.HandlerFunctions.http;
|
||||
import static org.springframework.cloud.gateway.server.mvc.predicate.GatewayRequestPredicates.host;
|
||||
import org.springframework.http.MediaType;
|
||||
|
||||
@Configuration
|
||||
class RouteConfiguration {
|
||||
|
||||
@Bean
|
||||
public RouterFunction<ServerResponse> gatewayRouterFunctionsAddReqHeader() {
|
||||
return route("rewrite_request_obj")
|
||||
.route(host("*.rewriterequestobj.org"), http("https://example.org"))
|
||||
.before(modifyResponseBody(String.class, String.class, MediaType.APPLICATION_JSON_VALUE, (request, s) -> s.toUpperCase()))
|
||||
.build();
|
||||
}
|
||||
|
||||
}
|
||||
----
|
||||
|
||||
NOTE: If the response has no body, the `RewriteFilter` is passed `null`. `Mono.empty()` should be returned to assign a missing body in the response.
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
[[prefixpath-filter]]
|
||||
= `PrefixPath` Filter
|
||||
:page-section-summary-toc: 1
|
||||
|
||||
The `PrefixPath` filter takes a single `prefix` parameter.
|
||||
The following example configures a `PrefixPath` filter:
|
||||
|
||||
.application.yml
|
||||
[source,yaml]
|
||||
----
|
||||
spring:
|
||||
cloud:
|
||||
gateway:
|
||||
routes:
|
||||
- id: prefixpath_route
|
||||
uri: https://example.org
|
||||
filters:
|
||||
- PrefixPath=/mypath
|
||||
----
|
||||
|
||||
.GatewaySampleApplication.java
|
||||
[source,java]
|
||||
----
|
||||
import static org.springframework.cloud.gateway.server.mvc.filter.BeforeFilterFunctions.prefixPath;
|
||||
import static org.springframework.cloud.gateway.server.mvc.handler.GatewayRouterFunctions.route;
|
||||
import static org.springframework.cloud.gateway.server.mvc.handler.HandlerFunctions.http;
|
||||
|
||||
@Configuration
|
||||
class RouteConfiguration {
|
||||
|
||||
@Bean
|
||||
public RouterFunction<ServerResponse> gatewayRouterFunctionsPrefixPath() {
|
||||
return route("prefixpath_route")
|
||||
.GET("/**", http("https://example.org"))
|
||||
.before("/mypath")
|
||||
.build();
|
||||
}
|
||||
}
|
||||
----
|
||||
|
||||
This prefixes `/mypath` to the path of all matching requests.
|
||||
So a request to `/hello` is sent to `/mypath/hello`.
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
[[preservehostheader-filter]]
|
||||
= `PreserveHostHeader` Filter
|
||||
:page-section-summary-toc: 1
|
||||
|
||||
The `PreserveHostHeader` filter has no parameters.
|
||||
This filter sets a request attribute that the `HandlerFunction` inspects to determine if the original host header should be sent rather than the host header determined by the HTTP client.
|
||||
The following example configures a `PreserveHostHeader` filter:
|
||||
|
||||
.application.yml
|
||||
[source,yaml]
|
||||
----
|
||||
spring:
|
||||
cloud:
|
||||
gateway:
|
||||
routes:
|
||||
- id: preserve_host_route
|
||||
uri: https://example.org
|
||||
filters:
|
||||
- PreserveHostHeader
|
||||
----
|
||||
|
||||
.GatewaySampleApplication.java
|
||||
[source,java]
|
||||
----
|
||||
import static org.springframework.cloud.gateway.server.mvc.filter.BeforeFilterFunctions.preserveHostHeader;
|
||||
import static org.springframework.cloud.gateway.server.mvc.handler.GatewayRouterFunctions.route;
|
||||
import static org.springframework.cloud.gateway.server.mvc.handler.HandlerFunctions.http;
|
||||
|
||||
@Configuration
|
||||
class RouteConfiguration {
|
||||
|
||||
@Bean
|
||||
public RouterFunction<ServerResponse> gatewayRouterFunctionsPreserveHostHeader() {
|
||||
return route("preserve_host_route")
|
||||
.GET("/**", http("https://example.org"))
|
||||
.before(preserveHostHeader())
|
||||
.build();
|
||||
}
|
||||
}
|
||||
----
|
||||
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
[[redirectto-filter]]
|
||||
= `RedirectTo` Filter
|
||||
|
||||
The `RedirectTo` filter takes two parameters, `status` and `url`.
|
||||
The `status` parameter should be a 300 series redirect HTTP code, such as 301.
|
||||
The `url` parameter should be a valid URL.
|
||||
This is the value of the `Location` header.
|
||||
For relative redirects, you should use `uri: no://op` as the uri of your route definition.
|
||||
The following listing configures a `RedirectTo` filter:
|
||||
|
||||
.application.yml
|
||||
[source,yaml]
|
||||
----
|
||||
spring:
|
||||
cloud:
|
||||
gateway:
|
||||
routes:
|
||||
- id: redirectto_route
|
||||
uri: https://example.org
|
||||
filters:
|
||||
- RedirectTo=302, https://acme.org
|
||||
----
|
||||
|
||||
.GatewaySampleApplication.java
|
||||
[source,java]
|
||||
----
|
||||
import static org.springframework.cloud.gateway.server.mvc.filter.FilterFunctions.redirectTo;
|
||||
import static org.springframework.cloud.gateway.server.mvc.handler.GatewayRouterFunctions.route;
|
||||
import static org.springframework.cloud.gateway.server.mvc.handler.HandlerFunctions.http;
|
||||
|
||||
@Configuration
|
||||
class RouteConfiguration {
|
||||
|
||||
@Bean
|
||||
public RouterFunction<ServerResponse> gatewayRouterFunctionsRedirectTo() {
|
||||
return route("redirectto_route")
|
||||
.GET("/**", http("https://example.org"))
|
||||
.filter(redirectTo(302, URI.create("acme.org")))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
----
|
||||
|
||||
This will send a status 302 with a `Location:https://acme.org` header to perform a redirect.
|
||||
@@ -0,0 +1,42 @@
|
||||
[[removejsonattributesresponsebody-filter]]
|
||||
= `RemoveJsonAttributesResponseBody` Filter
|
||||
|
||||
The `RemoveJsonAttributesResponseBody` filter takes a collection of `attribute names` to search for, an optional last parameter from the list can be a boolean to remove the attributes just at root level (that's the default value if not present at the end of the parameter configuration, `false`) or recursively (`true`).
|
||||
It provides a convenient method to apply a transformation to JSON body content by deleting attributes from it.
|
||||
|
||||
The following example configures an `RemoveJsonAttributesResponseBody` filter:
|
||||
|
||||
.application.yml
|
||||
[source,yaml]
|
||||
----
|
||||
spring:
|
||||
cloud:
|
||||
gateway:
|
||||
routes:
|
||||
- id: removejsonattributes_route
|
||||
uri: https://example.org
|
||||
filters:
|
||||
- RemoveJsonAttributesResponseBody=id,color
|
||||
----
|
||||
|
||||
This removes attributes "id" and "color" from the JSON content body at root level.
|
||||
|
||||
The following example configures an `RemoveJsonAttributesResponseBody` filter that uses the optional last parameter:
|
||||
|
||||
.application.yml
|
||||
[source,yaml]
|
||||
----
|
||||
spring:
|
||||
cloud:
|
||||
gateway:
|
||||
routes:
|
||||
- id: removejsonattributes_recursively_route
|
||||
uri: https://example.org
|
||||
predicates:
|
||||
- Path=/red/{segment}
|
||||
filters:
|
||||
- RemoveJsonAttributesResponseBody=id,color,true
|
||||
----
|
||||
|
||||
This removes attributes "id" and "color" from the JSON content body at any level.
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
[[removerequestheader-filter]]
|
||||
= `RemoveRequestHeader` GatewayFilter Factory
|
||||
:page-section-summary-toc: 1
|
||||
|
||||
The `RemoveRequestHeader` filter takes a `name` parameter.
|
||||
It is the name of the header to be removed.
|
||||
The following listing configures a `RemoveRequestHeader` filter:
|
||||
|
||||
.application.yml
|
||||
[source,yaml]
|
||||
----
|
||||
spring:
|
||||
cloud:
|
||||
gateway:
|
||||
routes:
|
||||
- id: removerequestheader_route
|
||||
uri: https://example.org
|
||||
filters:
|
||||
- RemoveRequestHeader=X-Request-Foo
|
||||
----
|
||||
|
||||
.GatewaySampleApplication.java
|
||||
[source,java]
|
||||
----
|
||||
import static org.springframework.cloud.gateway.server.mvc.filter.BeforeFilterFunctions.removeRequestHeader;
|
||||
import static org.springframework.cloud.gateway.server.mvc.handler.GatewayRouterFunctions.route;
|
||||
import static org.springframework.cloud.gateway.server.mvc.handler.HandlerFunctions.http;
|
||||
|
||||
@Configuration
|
||||
class RouteConfiguration {
|
||||
|
||||
@Bean
|
||||
public RouterFunction<ServerResponse> gatewayRouterFunctionsremoveRequestHeader() {
|
||||
return route("removerequestheader_route")
|
||||
.GET("/**", http("https://example.org"))
|
||||
.before(removeRequestHeader("X-Request-Foo"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
----
|
||||
|
||||
This removes the `X-Request-Foo` header before it is sent downstream.
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
[[removerequestparameter-filter]]
|
||||
= `RemoveRequestParameter` Filter
|
||||
:page-section-summary-toc: 1
|
||||
|
||||
The `RemoveRequestParameter` filter takes a `name` parameter.
|
||||
It is the name of the query parameter to be removed.
|
||||
The following example configures a `RemoveRequestParameter` filter:
|
||||
|
||||
.application.yml
|
||||
[source,yaml]
|
||||
----
|
||||
spring:
|
||||
cloud:
|
||||
gateway:
|
||||
routes:
|
||||
- id: removerequestparameter_route
|
||||
uri: https://example.org
|
||||
filters:
|
||||
- RemoveRequestParameter=red
|
||||
----
|
||||
|
||||
.GatewaySampleApplication.java
|
||||
[source,java]
|
||||
----
|
||||
import static org.springframework.cloud.gateway.server.mvc.filter.BeforeFilterFunctions.addRequestParameter;
|
||||
import static org.springframework.cloud.gateway.server.mvc.handler.GatewayRouterFunctions.route;
|
||||
import static org.springframework.cloud.gateway.server.mvc.handler.HandlerFunctions.http;
|
||||
|
||||
@Configuration
|
||||
class RouteConfiguration {
|
||||
|
||||
@Bean
|
||||
public RouterFunction<ServerResponse> gatewayRouterFunctionsAddReqHeader() {
|
||||
return route("removerequestparameter_route")
|
||||
.GET("/**", http("https://example.org"))
|
||||
.before(removeRequestParameter("red"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
----
|
||||
|
||||
This will remove the `red` parameter before it is sent downstream.
|
||||
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
[[removeresponseheader-filter]]
|
||||
= `RemoveResponseHeader` Filter
|
||||
|
||||
The `RemoveResponseHeader` filter takes a `name` parameter.
|
||||
It is the name of the header to be removed.
|
||||
The following listing configures a `RemoveResponseHeader` filter:
|
||||
|
||||
.application.yml
|
||||
[source,yaml]
|
||||
----
|
||||
spring:
|
||||
cloud:
|
||||
gateway:
|
||||
routes:
|
||||
- id: removeresponseheader_route
|
||||
uri: https://example.org
|
||||
filters:
|
||||
- RemoveResponseHeader=X-Response-Foo
|
||||
----
|
||||
|
||||
.GatewaySampleApplication.java
|
||||
[source,java]
|
||||
----
|
||||
import static org.springframework.cloud.gateway.server.mvc.filter.AfterFilterFunctions.removeResponseHeader;
|
||||
import static org.springframework.cloud.gateway.server.mvc.handler.GatewayRouterFunctions.route;
|
||||
import static org.springframework.cloud.gateway.server.mvc.handler.HandlerFunctions.http;
|
||||
|
||||
@Configuration
|
||||
class RouteConfiguration {
|
||||
|
||||
@Bean
|
||||
public RouterFunction<ServerResponse> gatewayRouterFunctionsRemoveResponseHeader() {
|
||||
return route("addresponseheader")
|
||||
.GET("/anything/addresheader", http("https://example.org"))
|
||||
.after(removeResponseHeader("X-Response-Foo"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
----
|
||||
|
||||
This will remove the `X-Response-Foo` header from the response before it is returned to the gateway client.
|
||||
|
||||
To remove any kind of sensitive header, you should configure this filter for any routes for which you may want to do so.
|
||||
In addition, you can configure this filter once by using `spring.cloud.gateway.default-filters` and have it applied to all routes.
|
||||
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
[[requestheadersize-filter]]
|
||||
= `RequestHeaderSize` Filter
|
||||
:page-section-summary-toc: 1
|
||||
|
||||
The `RequestHeaderSize` filter takes `maxSize` and `errorHeaderName` parameters.
|
||||
The `maxSize` parameter is the maximum data size allowed by the request header (including key and value). The `errorHeaderName` parameter sets the name of the response header containing an error message, by default it is "errorMessage".
|
||||
The following listing configures a `RequestHeaderSize` filter:
|
||||
|
||||
.application.yml
|
||||
[source,yaml]
|
||||
----
|
||||
spring:
|
||||
cloud:
|
||||
gateway:
|
||||
routes:
|
||||
- id: requestheadersize_route
|
||||
uri: https://example.org
|
||||
filters:
|
||||
- RequestHeaderSize=1000B
|
||||
----
|
||||
|
||||
.GatewaySampleApplication.java
|
||||
[source,java]
|
||||
----
|
||||
import static org.springframework.cloud.gateway.server.mvc.filter.BeforeFilterFunctions.requestHeaderSize;
|
||||
import static org.springframework.cloud.gateway.server.mvc.handler.GatewayRouterFunctions.route;
|
||||
import static org.springframework.cloud.gateway.server.mvc.handler.HandlerFunctions.http;
|
||||
|
||||
@Configuration
|
||||
class RouteConfiguration {
|
||||
|
||||
@Bean
|
||||
public RouterFunction<ServerResponse> gatewayRouterFunctionsRequestHeaderSize() {
|
||||
return route("requestheadersize_route")
|
||||
.GET("/**", http("https://example.org"))
|
||||
.before(requestHeaderSize("1000B"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
----
|
||||
|
||||
This will send a status 431 if size of any request header is greater than 1000 Bytes.
|
||||
|
||||
@@ -0,0 +1,120 @@
|
||||
[[requestratelimiter-filter]]
|
||||
= `RequestRateLimiter` Filter
|
||||
|
||||
The `RequestRateLimiter` filter uses a `RateLimiter` implementation to determine if the current request is allowed to proceed. If it is not, a status of `HTTP 429 - Too Many Requests` (by default) is returned.
|
||||
|
||||
This filter takes an optional `keyResolver` parameter and parameters specific to the rate limiter (described xref:spring-cloud-gateway/gatewayfilter-factories/requestratelimiter-factory.adoc#key-resolver-section[later in this section]).
|
||||
|
||||
`keyResolver` is a bean that implements the `KeyResolver` interface.
|
||||
In configuration, reference the bean by name using SpEL.
|
||||
`#{@myKeyResolver}` is a SpEL expression that references a bean named `myKeyResolver`.
|
||||
The following listing shows the `KeyResolver` interface:
|
||||
|
||||
.KeyResolver.java
|
||||
[source,java]
|
||||
----
|
||||
public interface KeyResolver {
|
||||
Mono<String> resolve(ServerWebExchange exchange);
|
||||
}
|
||||
----
|
||||
|
||||
[[key-resolver-section]]
|
||||
The `KeyResolver` interface lets pluggable strategies derive the key for limiting requests.
|
||||
In future milestone releases, there will be some `KeyResolver` implementations.
|
||||
|
||||
The default implementation of `KeyResolver` is the `PrincipalNameKeyResolver`, which retrieves the `Principal` from the `ServerWebExchange` and calls `Principal.getName()`.
|
||||
|
||||
By default, if the `KeyResolver` does not find a key, requests are denied.
|
||||
You can adjust this behavior by setting the `spring.cloud.gateway.filter.request-rate-limiter.deny-empty-key` (`true` or `false`) and `spring.cloud.gateway.filter.request-rate-limiter.empty-key-status-code` properties.
|
||||
|
||||
[NOTE]
|
||||
=====
|
||||
The `RequestRateLimiter` is not configurable with the "shortcut" notation. The following example below is _invalid_:
|
||||
|
||||
.application.properties
|
||||
----
|
||||
# INVALID SHORTCUT CONFIGURATION
|
||||
spring.cloud.gateway.routes[0].filters[0]=RequestRateLimiter=2, 2, #{@userkeyresolver}
|
||||
----
|
||||
=====
|
||||
|
||||
[[redis-ratelimiter]]
|
||||
== The Redis `RateLimiter`
|
||||
|
||||
The Redis implementation is based on work done at https://stripe.com/blog/rate-limiters[Stripe].
|
||||
It requires the use of the `spring-boot-starter-data-redis-reactive` Spring Boot starter.
|
||||
|
||||
The algorithm used is the https://en.wikipedia.org/wiki/Token_bucket[Token Bucket Algorithm].
|
||||
|
||||
The `redis-rate-limiter.replenishRate` property defines how many requests per second to allow (without any dropped requests).
|
||||
This is the rate at which the token bucket is filled.
|
||||
|
||||
The `redis-rate-limiter.burstCapacity` property is the maximum number of requests a user is allowed in a single second (without any dropped requests).
|
||||
This is the number of tokens the token bucket can hold.
|
||||
Setting this value to zero blocks all requests.
|
||||
|
||||
The `redis-rate-limiter.requestedTokens` property is how many tokens a request costs.
|
||||
This is the number of tokens taken from the bucket for each request and defaults to `1`.
|
||||
|
||||
A steady rate is accomplished by setting the same value in `replenishRate` and `burstCapacity`.
|
||||
Temporary bursts can be allowed by setting `burstCapacity` higher than `replenishRate`.
|
||||
In this case, the rate limiter needs to be allowed some time between bursts (according to `replenishRate`), as two consecutive bursts results in dropped requests (`HTTP 429 - Too Many Requests`).
|
||||
The following listing configures a `redis-rate-limiter`:
|
||||
|
||||
Rate limits below `1 request/s` are accomplished by setting `replenishRate` to the wanted number of requests, `requestedTokens` to the timespan in seconds, and `burstCapacity` to the product of `replenishRate` and `requestedTokens`.
|
||||
For example, setting `replenishRate=1`, `requestedTokens=60`, and `burstCapacity=60` results in a limit of `1 request/min`.
|
||||
.application.yml
|
||||
[source,yaml]
|
||||
----
|
||||
spring:
|
||||
cloud:
|
||||
gateway:
|
||||
routes:
|
||||
- id: requestratelimiter_route
|
||||
uri: https://example.org
|
||||
filters:
|
||||
- name: RequestRateLimiter
|
||||
args:
|
||||
redis-rate-limiter.replenishRate: 10
|
||||
redis-rate-limiter.burstCapacity: 20
|
||||
redis-rate-limiter.requestedTokens: 1
|
||||
|
||||
----
|
||||
|
||||
The following example configures a `KeyResolver` in Java:
|
||||
|
||||
.Config.java
|
||||
[source,java]
|
||||
----
|
||||
@Bean
|
||||
KeyResolver userKeyResolver() {
|
||||
return exchange -> Mono.just(exchange.getRequest().getQueryParams().getFirst("user"));
|
||||
}
|
||||
----
|
||||
|
||||
This defines a request rate limit of 10 per user. A burst of 20 is allowed, but, in the next second, only 10 requests are available.
|
||||
The `KeyResolver` is a simple one that gets the `user` request parameter
|
||||
NOTE: This is not recommended for production
|
||||
|
||||
You can also define a rate limiter as a bean that implements the `RateLimiter` interface.
|
||||
In configuration, you can reference the bean by name using SpEL.
|
||||
`#{@myRateLimiter}` is a SpEL expression that references a bean with named `myRateLimiter`.
|
||||
The following listing defines a rate limiter that uses the `KeyResolver` defined in the previous listing:
|
||||
|
||||
.application.yml
|
||||
[source,yaml]
|
||||
----
|
||||
spring:
|
||||
cloud:
|
||||
gateway:
|
||||
routes:
|
||||
- id: requestratelimiter_route
|
||||
uri: https://example.org
|
||||
filters:
|
||||
- name: RequestRateLimiter
|
||||
args:
|
||||
rate-limiter: "#{@myRateLimiter}"
|
||||
key-resolver: "#{@userKeyResolver}"
|
||||
|
||||
----
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
[[requestsize-filter]]
|
||||
= `RequestSize` Filter
|
||||
|
||||
When the request size is greater than the permissible limit, the `RequestSize` filter can restrict a request from reaching the downstream service.
|
||||
The filter takes a `maxSize` parameter.
|
||||
The `maxSize` is a `DataSize` type, so values can be defined as a number followed by an optional `DataUnit` suffix such as 'KB' or 'MB'. The default is 'B' for bytes.
|
||||
It is the permissible size limit of the request defined in bytes.
|
||||
The following listing configures a `RequestSize` filter:
|
||||
|
||||
.application.yml
|
||||
[source,yaml]
|
||||
----
|
||||
spring:
|
||||
cloud:
|
||||
gateway:
|
||||
routes:
|
||||
- id: request_size_route
|
||||
uri: http://localhost:8080
|
||||
predicates:
|
||||
- Path=/upload
|
||||
filters:
|
||||
- name: RequestSize
|
||||
args:
|
||||
maxSize: 5000000
|
||||
----
|
||||
|
||||
.GatewaySampleApplication.java
|
||||
[source,java]
|
||||
----
|
||||
import static org.springframework.cloud.gateway.server.mvc.filter.BeforeFilterFunctions.requestSize;
|
||||
import static org.springframework.cloud.gateway.server.mvc.handler.GatewayRouterFunctions.route;
|
||||
import static org.springframework.cloud.gateway.server.mvc.handler.HandlerFunctions.http;
|
||||
|
||||
@Configuration
|
||||
class RouteConfiguration {
|
||||
|
||||
@Bean
|
||||
public RouterFunction<ServerResponse> gatewayRouterFunctionsRequestSize() {
|
||||
return route("request_size_route")
|
||||
.GET("/upload", http("http://localhost:8080"))
|
||||
.before(requestSize("5000000"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
----
|
||||
|
||||
The `RequestSize` filter sets the response status as `413 Payload Too Large` with an additional header `errorMessage` when the request is rejected due to size. The following example shows such an `errorMessage`:
|
||||
|
||||
[source]
|
||||
----
|
||||
errorMessage : Request size is larger than permissible limit. Request size is 6.0 MB where permissible limit is 5.0 MB
|
||||
----
|
||||
|
||||
NOTE: The default request size is set to five MB if not provided as a filter argument in the route definition.
|
||||
|
||||
@@ -0,0 +1,86 @@
|
||||
[[retry-filter]]
|
||||
= `Retry` Filter
|
||||
|
||||
The `Retry` filter supports the following parameters:
|
||||
|
||||
* `retries`: The number of retries that should be attempted.
|
||||
* `statuses`: The HTTP status codes that should be retried, represented by using `org.springframework.http.HttpStatus`.
|
||||
* `methods`: The HTTP methods that should be retried, represented by using `org.springframework.http.HttpMethod`.
|
||||
* `series`: The series of status codes to be retried, represented by using `org.springframework.http.HttpStatus.Series`.
|
||||
* `exceptions`: A list of thrown exceptions that should be retried.
|
||||
* `backoff`: The configured exponential backoff for the retries.
|
||||
Retries are performed after a backoff interval of `firstBackoff * (factor ^ n)`, where `n` is the iteration.
|
||||
If `maxBackoff` is configured, the maximum backoff applied is limited to `maxBackoff`.
|
||||
If `basedOnPreviousValue` is true, the backoff is calculated by using `prevBackoff * factor`.
|
||||
|
||||
The following defaults are configured for `Retry` filter, if enabled:
|
||||
|
||||
* `retries`: Three times
|
||||
* `series`: 5XX series
|
||||
* `methods`: GET method
|
||||
* `exceptions`: `IOException` and `TimeoutException`
|
||||
* `backoff`: disabled
|
||||
|
||||
The following listing configures a Retry filter:
|
||||
|
||||
.application.yml
|
||||
[source,yaml]
|
||||
----
|
||||
spring:
|
||||
cloud:
|
||||
gateway:
|
||||
routes:
|
||||
- id: retry_test
|
||||
uri: http://localhost:8080/flakey
|
||||
predicates:
|
||||
- Host=*.retry.com
|
||||
filters:
|
||||
- name: Retry
|
||||
args:
|
||||
retries: 3
|
||||
statuses: BAD_GATEWAY
|
||||
methods: GET,POST
|
||||
backoff:
|
||||
firstBackoff: 10ms
|
||||
maxBackoff: 50ms
|
||||
factor: 2
|
||||
basedOnPreviousValue: false
|
||||
----
|
||||
|
||||
NOTE: When using the retry filter with a `forward:` prefixed URL, the target endpoint should be written carefully so that, in case of an error, it does not do anything that could result in a response being sent to the client and committed.
|
||||
For example, if the target endpoint is an annotated controller, the target controller method should not return `ResponseEntity` with an error status code.
|
||||
Instead, it should throw an `Exception` or signal an error (for example, through a `Mono.error(ex)` return value), which the retry filter can be configured to handle by retrying.
|
||||
|
||||
WARNING: When using the retry filter with any HTTP method with a body, the body will be cached and the gateway will become memory constrained. The body is cached in a request attribute defined by `ServerWebExchangeUtils.CACHED_REQUEST_BODY_ATTR`. The type of the object is `org.springframework.core.io.buffer.DataBuffer`.
|
||||
|
||||
A simplified "shortcut" notation can be added with a single `status` and `method`.
|
||||
|
||||
The following two examples are equivalent:
|
||||
|
||||
.application.yml
|
||||
[source,yaml]
|
||||
----
|
||||
spring:
|
||||
cloud:
|
||||
gateway:
|
||||
routes:
|
||||
- id: retry_route
|
||||
uri: https://example.org
|
||||
filters:
|
||||
- name: Retry
|
||||
args:
|
||||
retries: 3
|
||||
statuses: INTERNAL_SERVER_ERROR
|
||||
methods: GET
|
||||
backoff:
|
||||
firstBackoff: 10ms
|
||||
maxBackoff: 50ms
|
||||
factor: 2
|
||||
basedOnPreviousValue: false
|
||||
|
||||
- id: retryshortcut_route
|
||||
uri: https://example.org
|
||||
filters:
|
||||
- Retry=3,INTERNAL_SERVER_ERROR,GET,10ms,50ms,2,false
|
||||
----
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
[[rewritelocationresponseheader-filter]]
|
||||
= `RewriteLocationResponseHeader` Filter
|
||||
|
||||
The `RewriteLocationResponseHeader` filter modifies the value of the `Location` response header, usually to get rid of backend-specific details.
|
||||
It takes the `stripVersionMode`, `locationHeaderName`, `hostValue`, and `protocolsRegex` parameters.
|
||||
The following listing configures a `RewriteLocationResponseHeader` filter:
|
||||
|
||||
.application.yml
|
||||
[source,yaml]
|
||||
----
|
||||
spring:
|
||||
cloud:
|
||||
gateway:
|
||||
routes:
|
||||
- id: rewritelocationresponseheader_route
|
||||
uri: http://example.org
|
||||
filters:
|
||||
- RewriteLocationResponseHeader=AS_IN_REQUEST, Location, ,
|
||||
----
|
||||
|
||||
.GatewaySampleApplication.java
|
||||
[source,java]
|
||||
----
|
||||
import static org.springframework.cloud.gateway.server.mvc.filter.AfterFilterFunctions.addResponseHeader;
|
||||
import static org.springframework.cloud.gateway.server.mvc.filter.RewriteLocationResponseHeaderFilterFunctions.StripVersion;
|
||||
import static org.springframework.cloud.gateway.server.mvc.handler.GatewayRouterFunctions.route;
|
||||
import static org.springframework.cloud.gateway.server.mvc.handler.HandlerFunctions.http;
|
||||
|
||||
@Configuration
|
||||
class RouteConfiguration {
|
||||
|
||||
@Bean
|
||||
public RouterFunction<ServerResponse> gatewayRouterFunctionsRewriteLocationResponseHeader() {
|
||||
return route("rewritelocationresponseheader_route")
|
||||
.GET("/**", http("https://example.org"))
|
||||
.after(rewriteLocationResponseHeader(config -> config.setLocationHeaderName("Location").setStripVersion(StripVersion.AS_IN_REQUEST)))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
----
|
||||
|
||||
|
||||
|
||||
For example, for a request of `POST https://api.example.com/some/object/name`, the `Location` response header value of `https://object-service.prod.example.net/v2/some/object/id` is rewritten as `https://api.example.com/some/object/id`.
|
||||
|
||||
The `stripVersionMode` parameter has the following possible values: `NEVER_STRIP`, `AS_IN_REQUEST` (default), and `ALWAYS_STRIP`.
|
||||
|
||||
* `NEVER_STRIP`: The version is not stripped, even if the original request path contains no version.
|
||||
* `AS_IN_REQUEST`: The version is stripped only if the original request path contains no version.
|
||||
* `ALWAYS_STRIP`: The version is always stripped, even if the original request path contains version.
|
||||
|
||||
The `hostValue` parameter, if provided, is used to replace the `host:port` portion of the response `Location` header.
|
||||
If it is not provided, the value of the `Host` request header is used.
|
||||
|
||||
The `protocolsRegex` parameter must be a valid regex `String`, against which the protocol name is matched.
|
||||
If it is not matched, the filter does nothing.
|
||||
The default is `http|https|ftp|ftps`.
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
[[rewritepath-filter]]
|
||||
= `RewritePath` Filter
|
||||
|
||||
The `RewritePath` filter takes a path `regexp` parameter and a `replacement` parameter.
|
||||
This uses Java regular expressions for a flexible way to rewrite the request path.
|
||||
The following listing configures a `RewritePath` filter:
|
||||
|
||||
.application.yml
|
||||
[source,yaml]
|
||||
----
|
||||
spring:
|
||||
cloud:
|
||||
gateway:
|
||||
routes:
|
||||
- id: rewritepath_route
|
||||
uri: https://example.org
|
||||
predicates:
|
||||
- Path=/red/**
|
||||
filters:
|
||||
- RewritePath=/red/?(?<segment>.*), /$\{segment}
|
||||
----
|
||||
|
||||
.GatewaySampleApplication.java
|
||||
[source,java]
|
||||
----
|
||||
import static org.springframework.cloud.gateway.server.mvc.filter.BeforeFilterFunctions.rewritePath;
|
||||
import static org.springframework.cloud.gateway.server.mvc.handler.GatewayRouterFunctions.route;
|
||||
import static org.springframework.cloud.gateway.server.mvc.handler.HandlerFunctions.http;
|
||||
|
||||
@Configuration
|
||||
class RouteConfiguration {
|
||||
|
||||
@Bean
|
||||
public RouterFunction<ServerResponse> gatewayRouterFunctionsRewritePath() {
|
||||
return route("rewritepath_route")
|
||||
.GET("/red/**", http("https://example.org"))
|
||||
.before(rewritePath("/red/(?<segment>.*)", "/${segment}"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
----
|
||||
|
||||
For a request path of `/red/blue`, this sets the path to `/blue` before making the downstream request. Note that in `application.yml` the `$` should be replaced with `$\` because of the YAML specification.
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
= `RewriteRequestParameter` Filter
|
||||
|
||||
The `RewriteRequestParameter` filter takes a `name` parameter and a `replacement` parameter.
|
||||
It will rewrite the value of the request parameter of the given `name`.
|
||||
If multiple request parameters with the same `name` are set, they will be replaced with a single value.
|
||||
If no request parameter is found, no changes will be made.
|
||||
The following listing configures a `RewriteRequestParameter` filter:
|
||||
|
||||
.application.yml
|
||||
[source,yaml]
|
||||
----
|
||||
spring:
|
||||
cloud:
|
||||
gateway:
|
||||
routes:
|
||||
- id: rewriterequestparameter_route
|
||||
uri: https://example.org
|
||||
predicates:
|
||||
- Path=/products
|
||||
filters:
|
||||
- RewriteRequestParameter=campaign,fall2023
|
||||
----
|
||||
|
||||
.GatewaySampleApplication.java
|
||||
[source,java]
|
||||
----
|
||||
import static org.springframework.cloud.gateway.server.mvc.filter.BeforeFilterFunctions.addRequestParameter;
|
||||
import static org.springframework.cloud.gateway.server.mvc.handler.GatewayRouterFunctions.route;
|
||||
import static org.springframework.cloud.gateway.server.mvc.handler.HandlerFunctions.http;
|
||||
|
||||
@Configuration
|
||||
class RouteConfiguration {
|
||||
|
||||
@Bean
|
||||
public RouterFunction<ServerResponse> gatewayRouterFunctionsAddReqHeader() {
|
||||
return route("add_request_parameter_route")
|
||||
.GET("/anything/addrequestparam", http("https://example.org"))
|
||||
.before(addRequestParameter("red", "blue"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
----
|
||||
|
||||
For a request to `/products?campaign=old`, this sets the request parameter to `campaign=fall2023`.
|
||||
@@ -0,0 +1,44 @@
|
||||
[[rewriteresponseheader-filter]]
|
||||
= `RewriteResponseHeader` Filter
|
||||
:page-section-summary-toc: 1
|
||||
|
||||
The `RewriteResponseHeader` filter takes `name`, `regexp`, and `replacement` parameters.
|
||||
It uses Java regular expressions for a flexible way to rewrite the response header value.
|
||||
The following example configures a `RewriteResponseHeader` filter:
|
||||
|
||||
.application.yml
|
||||
[source,yaml]
|
||||
----
|
||||
spring:
|
||||
cloud:
|
||||
gateway:
|
||||
routes:
|
||||
- id: rewriteresponseheader_route
|
||||
uri: https://example.org
|
||||
filters:
|
||||
- RewriteResponseHeader=X-Response-Red, , password=[^&]+, password=***
|
||||
----
|
||||
|
||||
.GatewaySampleApplication.java
|
||||
[source,java]
|
||||
----
|
||||
import static org.springframework.cloud.gateway.server.mvc.filter.AfterFilterFunctions.addResponseHeader;
|
||||
import static org.springframework.cloud.gateway.server.mvc.handler.GatewayRouterFunctions.route;
|
||||
import static org.springframework.cloud.gateway.server.mvc.handler.HandlerFunctions.http;
|
||||
|
||||
@Configuration
|
||||
class RouteConfiguration {
|
||||
|
||||
@Bean
|
||||
public RouterFunction<ServerResponse> gatewayRouterFunctionsRewriteResponseHeader() {
|
||||
return route("rewriteresponseheader_route")
|
||||
.GET("/**", http("https://example.org"))
|
||||
.after(rewriteResponseHeader("X-Request-Red", "password=[^&]+", "password=***"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
----
|
||||
|
||||
For a header value of `/42?user=ford&password=omg!what&flag=true`, it is set to `/42?user=ford&password=\***&flag=true` after making the downstream request.
|
||||
You must use `$\` to mean `$` because of the YAML specification in `application.yml`.
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
[[savesession-filter]]
|
||||
= `SaveSession` Filter
|
||||
|
||||
The `SaveSession` filter forces a `WebSession::save` operation _before_ forwarding the call downstream.
|
||||
This is of particular use when using something like https://projects.spring.io/spring-session/[Spring Session] with a lazy data store, and you need to ensure the session state has been saved before making the forwarded call.
|
||||
The following example configures a `SaveSession` filter:
|
||||
|
||||
.application.yml
|
||||
[source,yaml]
|
||||
----
|
||||
spring:
|
||||
cloud:
|
||||
gateway:
|
||||
routes:
|
||||
- id: save_session
|
||||
uri: https://example.org
|
||||
predicates:
|
||||
- Path=/foo/**
|
||||
filters:
|
||||
- SaveSession
|
||||
----
|
||||
|
||||
If you integrate https://projects.spring.io/spring-security/[Spring Security] with Spring Session and want to ensure security details have been forwarded to the remote process, this is critical.
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
[[secureheaders-filter]]
|
||||
= `SecureHeaders` Filter
|
||||
|
||||
The `SecureHeaders` filter adds a number of headers to the response, per the recommendation made in https://blog.appcanary.com/2017/http-security-headers.html[this blog post].
|
||||
|
||||
The following headers (shown with their default values) are added:
|
||||
|
||||
* `X-Xss-Protection:1 (mode=block`)
|
||||
* `Strict-Transport-Security (max-age=631138519`)
|
||||
* `X-Frame-Options (DENY)`
|
||||
* `X-Content-Type-Options (nosniff)`
|
||||
* `Referrer-Policy (no-referrer)`
|
||||
* `Content-Security-Policy (default-src 'self' https:; font-src 'self' https: data:; img-src 'self' https: data:; object-src 'none'; script-src https:; style-src 'self' https: 'unsafe-inline)'`
|
||||
* `X-Download-Options (noopen)`
|
||||
* `X-Permitted-Cross-Domain-Policies (none)`
|
||||
|
||||
To change the default values, set the appropriate property in the `spring.cloud.gateway.filter.secure-headers` namespace.
|
||||
The following properties are available:
|
||||
|
||||
* `xss-protection-header`
|
||||
* `strict-transport-security`
|
||||
* `frame-options`
|
||||
* `content-type-options`
|
||||
* `referrer-policy`
|
||||
* `content-security-policy`
|
||||
* `download-options`
|
||||
* `permitted-cross-domain-policies`
|
||||
|
||||
To disable the default values set the `spring.cloud.gateway.filter.secure-headers.disable` property with comma-separated values.
|
||||
The following example shows how to do so:
|
||||
|
||||
[source]
|
||||
----
|
||||
spring.cloud.gateway.filter.secure-headers.disable=x-frame-options,strict-transport-security
|
||||
----
|
||||
|
||||
NOTE: The lowercase full name of the secure header needs to be used to disable it..
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
[[setpath-filter]]
|
||||
= `SetPath` Filter
|
||||
|
||||
The `SetPath` filter takes a path `template` parameter.
|
||||
It offers a simple way to manipulate the request path by allowing templated segments of the path.
|
||||
This uses the URI templates from Spring Framework.
|
||||
Multiple matching segments are allowed.
|
||||
The following example configures a `SetPath` filter:
|
||||
|
||||
.application.yml
|
||||
[source,yaml]
|
||||
----
|
||||
spring:
|
||||
cloud:
|
||||
gateway:
|
||||
routes:
|
||||
- id: setpath_route
|
||||
uri: https://example.org
|
||||
predicates:
|
||||
- Path=/red/{segment}
|
||||
filters:
|
||||
- SetPath=/{segment}
|
||||
----
|
||||
|
||||
.GatewaySampleApplication.java
|
||||
[source,java]
|
||||
----
|
||||
import static org.springframework.cloud.gateway.server.mvc.filter.BeforeFilterFunctions.setPath;
|
||||
import static org.springframework.cloud.gateway.server.mvc.handler.GatewayRouterFunctions.route;
|
||||
import static org.springframework.cloud.gateway.server.mvc.handler.HandlerFunctions.http;
|
||||
|
||||
@Configuration
|
||||
class RouteConfiguration {
|
||||
|
||||
@Bean
|
||||
public RouterFunction<ServerResponse> gatewayRouterFunctionsSetPath() {
|
||||
return route("add_request_parameter_route")
|
||||
.GET("/red/{segment}", http("https://example.org"))
|
||||
.before(setPath("/{segment"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
----
|
||||
|
||||
For a request path of `/red/blue`, this sets the path to `/blue` before making the downstream request.
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
[[setrequestheader-filter]]
|
||||
= `SetRequestHeader` Filter
|
||||
|
||||
The `SetRequestHeader` filter takes `name` and `value` parameters.
|
||||
The following listing configures a `SetRequestHeader` filter:
|
||||
|
||||
.application.yml
|
||||
[source,yaml]
|
||||
----
|
||||
spring:
|
||||
cloud:
|
||||
gateway:
|
||||
routes:
|
||||
- id: setrequestheader_route
|
||||
uri: https://example.org
|
||||
filters:
|
||||
- SetRequestHeader=X-Request-Red, Blue
|
||||
----
|
||||
|
||||
.GatewaySampleApplication.java
|
||||
[source,java]
|
||||
----
|
||||
import static org.springframework.cloud.gateway.server.mvc.filter.BeforeFilterFunctions.setRequestHostHeader;
|
||||
import static org.springframework.cloud.gateway.server.mvc.handler.GatewayRouterFunctions.route;
|
||||
import static org.springframework.cloud.gateway.server.mvc.handler.HandlerFunctions.http;
|
||||
|
||||
@Configuration
|
||||
class RouteConfiguration {
|
||||
|
||||
@Bean
|
||||
public RouterFunction<ServerResponse> gatewayRouterFunctionsSetRequestHeader() {
|
||||
return route("add_request_parameter_route")
|
||||
.GET("/**", http("https://example.org"))
|
||||
.before(setRequestHostHeader("X-Request-Red", "Blue"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
----
|
||||
|
||||
This filter replaces (rather than adding) all headers with the given name.
|
||||
So, if the downstream server responded with `X-Request-Red:1234`, it will be replaced with `X-Request-Red:Blue`, which is what the downstream service would receive.
|
||||
|
||||
`SetRequestHeader` is aware of URI variables used to match a path or host.
|
||||
URI variables may be used in the value and are expanded at runtime.
|
||||
The following example configures an `SetRequestHeader` filter that uses a variable:
|
||||
|
||||
.application.yml
|
||||
[source,yaml]
|
||||
----
|
||||
spring:
|
||||
cloud:
|
||||
gateway:
|
||||
routes:
|
||||
- id: setrequestheader_route
|
||||
uri: https://example.org
|
||||
predicates:
|
||||
- Host: {segment}.myhost.org
|
||||
filters:
|
||||
- SetRequestHeader=X-Request-Red, Blue-{segment}
|
||||
----
|
||||
|
||||
.GatewaySampleApplication.java
|
||||
[source,java]
|
||||
----
|
||||
import static org.springframework.cloud.gateway.server.mvc.filter.BeforeFilterFunctions.setRequestHostHeader;
|
||||
import static org.springframework.cloud.gateway.server.mvc.handler.GatewayRouterFunctions.route;
|
||||
import static org.springframework.cloud.gateway.server.mvc.handler.HandlerFunctions.http;
|
||||
import static import static org.springframework.cloud.gateway.server.mvc.predicate.GatewayRequestPredicates.host;
|
||||
|
||||
@Configuration
|
||||
class RouteConfiguration {
|
||||
|
||||
@Bean
|
||||
public RouterFunction<ServerResponse> gatewayRouterFunctionsSetRequestHeader() {
|
||||
return route("add_request_parameter_route")
|
||||
.route(host("{segment}.myhost.org"), http("https://example.org"))
|
||||
.before(setRequestHostHeader("X-Request-Red", "Blue-{segment}"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
----
|
||||
@@ -0,0 +1,47 @@
|
||||
[[setrequesthostheader-filter]]
|
||||
= `SetRequestHostHeader` Filter
|
||||
|
||||
There are certain situation when the host header may need to be overridden. In this situation, the `SetRequestHostHeader` filter can replace the existing host header with a specified value.
|
||||
The filter takes a `host` parameter.
|
||||
The following listing configures a `SetRequestHostHeader` filter:
|
||||
|
||||
.application.yml
|
||||
[source,yaml]
|
||||
----
|
||||
spring:
|
||||
cloud:
|
||||
gateway:
|
||||
routes:
|
||||
- id: set_request_host_header_route
|
||||
uri: http://localhost:8080
|
||||
predicates:
|
||||
- Path=/headers
|
||||
filters:
|
||||
- name: SetRequestHostHeader
|
||||
args:
|
||||
host: example.org
|
||||
----
|
||||
|
||||
.GatewaySampleApplication.java
|
||||
[source,java]
|
||||
----
|
||||
import static org.springframework.cloud.gateway.server.mvc.filter.BeforeFilterFunctions.setRequestHostHeader;
|
||||
import static org.springframework.cloud.gateway.server.mvc.handler.GatewayRouterFunctions.route;
|
||||
import static org.springframework.cloud.gateway.server.mvc.handler.HandlerFunctions.http;
|
||||
|
||||
@Configuration
|
||||
class RouteConfiguration {
|
||||
|
||||
@Bean
|
||||
public RouterFunction<ServerResponse> gatewayRouterFunctionsSetRequestHostHeader() {
|
||||
return route("set_request_host_header_route")
|
||||
.GET("/headers", http("http://localhost:8080"))
|
||||
.before(setRequestHostHeader("example.org"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
----
|
||||
|
||||
The `SetRequestHostHeader` filter replaces the value of the host header with `example.org`.
|
||||
|
||||
|
||||
@@ -0,0 +1,82 @@
|
||||
[[setresponseheader-filter]]
|
||||
= `SetResponseHeader` Filter
|
||||
|
||||
The `SetResponseHeader` filter takes `name` and `value` parameters.
|
||||
The following listing configures a `SetResponseHeader` filter:
|
||||
|
||||
.application.yml
|
||||
[source,yaml]
|
||||
----
|
||||
spring:
|
||||
cloud:
|
||||
gateway:
|
||||
routes:
|
||||
- id: setresponseheader_route
|
||||
uri: https://example.org
|
||||
filters:
|
||||
- SetResponseHeader=X-Response-Red, Blue
|
||||
----
|
||||
|
||||
.GatewaySampleApplication.java
|
||||
[source,java]
|
||||
----
|
||||
import static org.springframework.cloud.gateway.server.mvc.filter.AfterFilterFunctions.setResponseHeader;
|
||||
import static org.springframework.cloud.gateway.server.mvc.handler.GatewayRouterFunctions.route;
|
||||
import static org.springframework.cloud.gateway.server.mvc.handler.HandlerFunctions.http;
|
||||
|
||||
@Configuration
|
||||
class RouteConfiguration {
|
||||
|
||||
@Bean
|
||||
public RouterFunction<ServerResponse> gatewayRouterFunctionsSetResponseHeader() {
|
||||
return route("addresponseheader")
|
||||
.GET("/anything/addresheader", http("https://example.org"))
|
||||
.after(setResponseHeader("X-Response-Red", "Blue"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
----
|
||||
|
||||
This GatewayFilter replaces (rather than adding) all headers with the given name.
|
||||
So, if the downstream server responded with `X-Response-Red:1234`, it will be replaced with `X-Response-Red:Blue`, which is what the gateway client would receive.
|
||||
|
||||
`SetResponseHeader` is aware of URI variables used to match a path or host.
|
||||
URI variables may be used in the value and will be expanded at runtime.
|
||||
The following example configures an `SetResponseHeader` filter that uses a variable:
|
||||
|
||||
.application.yml
|
||||
[source,yaml]
|
||||
----
|
||||
spring:
|
||||
cloud:
|
||||
gateway:
|
||||
routes:
|
||||
- id: setresponseheader_route
|
||||
uri: https://example.org
|
||||
predicates:
|
||||
- Host: {segment}.myhost.org
|
||||
filters:
|
||||
- SetResponseHeader=foo, bar-{segment}
|
||||
----
|
||||
|
||||
.GatewaySampleApplication.java
|
||||
[source,java]
|
||||
----
|
||||
import static org.springframework.cloud.gateway.server.mvc.filter.AfterFilterFunctions.setResponseHeader;
|
||||
import static org.springframework.cloud.gateway.server.mvc.handler.GatewayRouterFunctions.route;
|
||||
import static org.springframework.cloud.gateway.server.mvc.handler.HandlerFunctions.http;
|
||||
import static org.springframework.cloud.gateway.server.mvc.predicate.GatewayRequestPredicates.host;
|
||||
|
||||
@Configuration
|
||||
class RouteConfiguration {
|
||||
|
||||
@Bean
|
||||
public RouterFunction<ServerResponse> gatewayRouterFunctionsSetResponseHeader() {
|
||||
return route("add_response_header_route")
|
||||
.route(host("{segment}.myhost.org"), http("https://example.org"))
|
||||
.after(setResponseHeader("foo", "bar-{segment}"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
----
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
[[setstatus-filter]]
|
||||
= `SetStatus` Filter
|
||||
|
||||
The `SetStatus` filter takes a single parameter, `status`.
|
||||
It must be a valid Spring `HttpStatus`.
|
||||
It may be the integer value `404` or the string representation of the enumeration: `NOT_FOUND`.
|
||||
The following listing configures a `SetStatus` filter:
|
||||
|
||||
.application.yml
|
||||
[source,yaml]
|
||||
----
|
||||
spring:
|
||||
cloud:
|
||||
gateway:
|
||||
routes:
|
||||
- id: setstatusstring_route
|
||||
uri: https://example.org
|
||||
filters:
|
||||
- SetStatus=UNAUTHORIZED
|
||||
- id: setstatusint_route
|
||||
uri: https://example.org
|
||||
filters:
|
||||
- SetStatus=401
|
||||
----
|
||||
|
||||
.GatewaySampleApplication.java
|
||||
[source,java]
|
||||
----
|
||||
import static org.springframework.cloud.gateway.server.mvc.filter.AfterFilterFunctions.setStatus;
|
||||
import static org.springframework.cloud.gateway.server.mvc.handler.GatewayRouterFunctions.route;
|
||||
import static org.springframework.cloud.gateway.server.mvc.handler.HandlerFunctions.http;
|
||||
|
||||
@Configuration
|
||||
class RouteConfiguration {
|
||||
|
||||
@Bean
|
||||
public RouterFunction<ServerResponse> gatewayRouterFunctionsSetStatus() {
|
||||
return route("setstatus_route")
|
||||
.GET("/path1", http("https://example.org"))
|
||||
// setStatus("UNAUTHORIZED") works as well
|
||||
.after(setStatus(HttpStatus.UNAUTHORIZED))
|
||||
.build().and(route("setstatusint_route")
|
||||
.GET("/path2", http("https://example.org"))
|
||||
.after(setStatus("401"))
|
||||
.build());
|
||||
}
|
||||
}
|
||||
----
|
||||
|
||||
In either case, the HTTP status of the response is set to 401.
|
||||
|
||||
////
|
||||
TODO: support original status header
|
||||
You can configure the `SetStatus` filter to return the original HTTP status code from the proxied request in a header in the response.
|
||||
The header is added to the response if configured with the following property:
|
||||
|
||||
.application.yml
|
||||
[source,yaml]
|
||||
----
|
||||
spring:
|
||||
cloud:
|
||||
gateway:
|
||||
set-status:
|
||||
original-status-header-name: original-http-status
|
||||
----
|
||||
////
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
[[stripprefix-filter]]
|
||||
= `StripPrefix` Filter
|
||||
|
||||
The `StripPrefix` filter takes one parameter, `parts`.
|
||||
The `parts` parameter indicates the number of parts in the path to strip from the request before sending it downstream.
|
||||
The following listing configures a `StripPrefix` filter:
|
||||
|
||||
.application.yml
|
||||
[source,yaml]
|
||||
----
|
||||
spring:
|
||||
cloud:
|
||||
gateway:
|
||||
routes:
|
||||
- id: nameRoot
|
||||
uri: https://nameservice
|
||||
predicates:
|
||||
- Path=/name/**
|
||||
filters:
|
||||
- StripPrefix=2
|
||||
----
|
||||
|
||||
.GatewaySampleApplication.java
|
||||
[source,java]
|
||||
----
|
||||
import static org.springframework.cloud.gateway.server.mvc.filter.BeforeFilterFunctions.stripPrefix;
|
||||
import static org.springframework.cloud.gateway.server.mvc.handler.GatewayRouterFunctions.route;
|
||||
import static org.springframework.cloud.gateway.server.mvc.handler.HandlerFunctions.http;
|
||||
|
||||
@Configuration
|
||||
class RouteConfiguration {
|
||||
|
||||
@Bean
|
||||
public RouterFunction<ServerResponse> gatewayRouterFunctionsStripPrefix() {
|
||||
return route("nameRoot")
|
||||
.GET("/name/**", http("https://example.org"))
|
||||
.before(stripPrefix(2))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
----
|
||||
|
||||
When a request is made through the gateway to `/name/blue/red`, the request made to `nameservice` looks like `https://nameservice/red`.
|
||||
|
||||
@@ -0,0 +1,103 @@
|
||||
[[tokenrelay-filter]]
|
||||
= `TokenRelay` Filter
|
||||
|
||||
A Token Relay is where an OAuth2 consumer acts as a Client and
|
||||
forwards the incoming token to outgoing resource requests. The
|
||||
consumer can be a pure Client (like an SSO application) or a Resource
|
||||
Server.
|
||||
|
||||
Spring Cloud Gateway can forward OAuth2 access tokens downstream to the services
|
||||
it is proxying using the `TokenRelay` filter.
|
||||
|
||||
The `TokenRelay` filter takes one optional parameter, `clientRegistrationId`.
|
||||
The following example configures a `TokenRelay` filter:
|
||||
|
||||
.App.java
|
||||
[source,java]
|
||||
----
|
||||
|
||||
@Bean
|
||||
public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {
|
||||
return builder.routes()
|
||||
.route("resource", r -> r.path("/resource")
|
||||
.filters(f -> f.tokenRelay("myregistrationid"))
|
||||
.uri("http://localhost:9000"))
|
||||
.build();
|
||||
}
|
||||
----
|
||||
|
||||
or this
|
||||
|
||||
.application.yaml
|
||||
[source,yaml]
|
||||
----
|
||||
spring:
|
||||
cloud:
|
||||
gateway:
|
||||
routes:
|
||||
- id: resource
|
||||
uri: http://localhost:9000
|
||||
predicates:
|
||||
- Path=/resource
|
||||
filters:
|
||||
- TokenRelay=myregistrationid
|
||||
----
|
||||
|
||||
The example above specifies a `clientRegistrationId`, which can be used to obtain and forward an OAuth2 access token for any available `ClientRegistration`.
|
||||
|
||||
Spring Cloud Gateway can also forward the OAuth2 access token of the currently authenticated user `oauth2Login()` is used to authenticate the user.
|
||||
To add this functionality to the gateway, you can omit the `clientRegistrationId` parameter like this:
|
||||
|
||||
.App.java
|
||||
[source,java]
|
||||
----
|
||||
|
||||
@Bean
|
||||
public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {
|
||||
return builder.routes()
|
||||
.route("resource", r -> r.path("/resource")
|
||||
.filters(f -> f.tokenRelay())
|
||||
.uri("http://localhost:9000"))
|
||||
.build();
|
||||
}
|
||||
----
|
||||
|
||||
or this
|
||||
|
||||
.application.yaml
|
||||
[source,yaml]
|
||||
----
|
||||
spring:
|
||||
cloud:
|
||||
gateway:
|
||||
routes:
|
||||
- id: resource
|
||||
uri: http://localhost:9000
|
||||
predicates:
|
||||
- Path=/resource
|
||||
filters:
|
||||
- TokenRelay=
|
||||
----
|
||||
|
||||
and it will (in addition to logging the user in and grabbing a token)
|
||||
pass the authentication token downstream to the services (in this case
|
||||
`/resource`).
|
||||
|
||||
To enable this for Spring Cloud Gateway add the following dependencies
|
||||
|
||||
- `org.springframework.boot:spring-boot-starter-oauth2-client`
|
||||
|
||||
How does it work? The {github-code}/src/main/java/org/springframework/cloud/gateway/security/TokenRelayGatewayFilterFactory.java[filter]
|
||||
extracts an OAuth2 access token from the currently authenticated user for the provided `clientRegistrationId`.
|
||||
If no `clientRegistrationId` is provided, the currently authenticated user's own access token (obtained during login) is used.
|
||||
In either case, the extracted access token is placed in a request header for the downstream requests.
|
||||
|
||||
For a full working sample see https://github.com/spring-cloud-samples/sample-gateway-oauth2login[this project].
|
||||
|
||||
NOTE: A `TokenRelayGatewayFilterFactory` bean will only be created if the proper `spring.security.oauth2.client.*` properties are set which will trigger creation of a `ReactiveClientRegistrationRepository` bean.
|
||||
|
||||
NOTE: The default implementation of `ReactiveOAuth2AuthorizedClientService` used by `TokenRelayGatewayFilterFactory`
|
||||
uses an in-memory data store. You will need to provide your own implementation `ReactiveOAuth2AuthorizedClientService`
|
||||
if you need a more robust solution.
|
||||
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
[[gateway-handler-filter-functions]]
|
||||
= Gateway Handler Filter Functions
|
||||
|
||||
[[beforefilterfunctions]]
|
||||
== Before Filter Functions
|
||||
|
||||
The WebMvc.fn API has the concept of a "before" filter function, a `java.util.Function<ServerRequest, ServerRequest>` that only acts on the request. Many before filter functions are referenced in `org.springframework.cloud.gateway.server.mvc.filter.BeforeFilterFunctions` as static factory methods. They are adapted to generic `org.springframework.web.servlet.function.HandlerFilterFunction<ServerResponse, ServerResponse>` in `org.springframework.cloud.gateway.server.mvc.filter.FilterFunctions`. Either may be used, but the more specific `BeforeFilterFunctions` is preferred, where possible, as it is more explicit.
|
||||
|
||||
[[afterfilterfunctions]]
|
||||
== After Filter Functions
|
||||
|
||||
The WebMvc.fn API has the concept of a "after" filter function, a `java.util.BiFunction<ServerRequest, ServerResponse, ServerResponse>` that can modify the response. Many after filter functions are referenced in `org.springframework.cloud.gateway.server.mvc.filter.AfterFilterFunctions` as static factory methods. They are adapted to generic `org.springframework.web.servlet.function.HandlerFilterFunction<ServerResponse, ServerResponse>` in `org.springframework.cloud.gateway.server.mvc.filter.FilterFunctions`. Either may be used, but the more specific `AfterFilterFunctions` is preferred, where possible, as it is more explicit.
|
||||
|
||||
== Advanced Filter Functions
|
||||
|
||||
Some filters can not be classified as a simple before or after filter. These filters do work both prior to and after the proxy request has been made. Some of these include filters located in `BodyFilterFunctions`, `Bucket4jFilterFunctions, `CircuitBreakerFilterFunctions`, `LoadBalancerFilterFunctions`, `RetryFilterFunctions`, and `TokenRelayFilterFunctions`, all located in the `org.springframework.cloud.gateway.server.mvc.filter` package.
|
||||
@@ -0,0 +1,4 @@
|
||||
[[gateway-request-predicates]]
|
||||
= Gateway Request Predicates
|
||||
|
||||
TODO
|
||||
@@ -38,4 +38,9 @@ class SimpleGateway {
|
||||
return route("simple_route").GET("/get", http("https://httpbin.org"));
|
||||
}
|
||||
}
|
||||
----
|
||||
----
|
||||
|
||||
[[gateway-handlerfunctions]]
|
||||
== Gateway MVC Handler Functions
|
||||
|
||||
Various `RouterFunctions.Builder` methods require a `HandlerFunction<ServerResponse>`. To create a route that is proxied by the MVC Gateway, `HandlerFunction` implementations are supplied in `org.springframework.cloud.gateway.server.mvc.handler.HandlerFunctions`. The most basic is the `http()` `HandlerFunction`. If a `URI` is supplied as a parameter, that is the `URI` used as the downstream target for sending the HTTP requests (as seen in the example above). If no parameter is passed, the function looks for a `URI` in the `org.springframework.cloud.gateway.server.mvc.common.MvcUtils.GATEWAY_REQUEST_URL_ATTR` request attribute. This allows for dynamic targets such as load balancing to set the `URI`.
|
||||
@@ -0,0 +1,4 @@
|
||||
[[writing-custom-predicates-and-filters]]
|
||||
= Writing Custom Predicates and Filters
|
||||
|
||||
TODO
|
||||
Reference in New Issue
Block a user