Initial documentation.

Includes general documentation and most filters.

TODO: request predicates and custome dev docs.
This commit is contained in:
sgibb
2023-12-04 15:39:49 -05:00
parent da19814649
commit ff98d6298c
40 changed files with 2104 additions and 1 deletions

View File

@@ -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

View File

@@ -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}"));
}
}
----

View File

@@ -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}
----

View File

@@ -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();
}
}
----

View File

@@ -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();
}
}
----

View File

@@ -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();
}
}
----

View File

@@ -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`.

View File

@@ -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].

View File

@@ -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`.

View File

@@ -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.

View File

@@ -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.

View File

@@ -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.

View File

@@ -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`.

View File

@@ -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();
}
}
----

View File

@@ -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.

View File

@@ -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.

View File

@@ -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.

View File

@@ -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.

View File

@@ -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.

View File

@@ -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.

View File

@@ -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}"
----

View File

@@ -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.

View File

@@ -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
----

View File

@@ -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`.

View File

@@ -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.

View File

@@ -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`.

View File

@@ -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`.

View File

@@ -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.

View File

@@ -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..

View File

@@ -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.

View File

@@ -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();
}
}
----

View File

@@ -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`.

View File

@@ -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();
}
}
----

View File

@@ -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
----
////

View File

@@ -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`.

View File

@@ -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.

View File

@@ -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.

View File

@@ -0,0 +1,4 @@
[[gateway-request-predicates]]
= Gateway Request Predicates
TODO

View File

@@ -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`.

View File

@@ -0,0 +1,4 @@
[[writing-custom-predicates-and-filters]]
= Writing Custom Predicates and Filters
TODO