1. Quick start
Route filters allow modification of incoming HTTP requests and outgoing HTTP responses. Spring Cloud Gateway includes a number of built-in GatewayFilter Factories.
Filters are generally used together with predicates. When the xxx condition is met, the logic of a certain filter is executed.
Routes can be configured through configuration files and codes.
The following is how to write java code:
@Bean
public RouteLocator routes(RouteLocatorBuilder builder) {
return builder.routes()
.route("circuitbreaker_route", r -> r.path("/consumingServiceEndpoint")
.filters(f -> f.circuitBreaker(c -> c.name("myCircuitBreaker").fallbackUri("forward:/inCaseOfFailureUseThis"))
.rewritePath("/consumingServiceEndpoint", "/backingServiceEndpoint")).uri("lb://backing-service:8088")
.build();
}
The configuration is written briefly, see the example below.
2. Basic principles
The function of GatewayFilterFactory is to generate GatewayFilter.
The function of GatewayFilter is to process requests or return messages.
The following is a piece of source code. The function of the GatewayFilter is to add a request header, and this request header is defined in the configuration file.
public class AddRequestHeaderGatewayFilterFactory extends AbstractNameValueGatewayFilterFactory {
@Override
public GatewayFilter apply(NameValueConfig config) {
return new GatewayFilter() {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
String value = ServerWebExchangeUtils.expand(exchange, config.getValue());
ServerHttpRequest request = exchange.getRequest().mutate()
.headers(httpHeaders -> httpHeaders.add(config.getName(), value)).build();
return chain.filter(exchange.mutate().request(request).build());
}
@Override
public String toString() {
return filterToStringCreator(AddRequestHeaderGatewayFilterFactory.this)
.append(config.getName(), config.getValue()).toString();
}
};
}
}
The essence of GateWayFilterFactory is to parse the configuration and add Filter to the specified route in order to process the request message.
3. Filter Example
3.1 The AddRequestHeader GatewayFilter Factory
spring:
cloud:
gateway:
routes:
- id: add_request_header_route
uri: https://example.org
predicates:
- Path=/red/{
segment}
filters:
- AddRequestHeader=X-Request-Red, Blue-{
segment}
Add header information: X-Request-Red, value is Blue-{segment}, segment is the information in the path
3.2 The AddRequestParameter GatewayFilter Factory
spring:
cloud:
gateway:
routes:
- id: add_request_parameter_route
uri: https://example.org
predicates:
- Host: {
segment}.myhost.org
filters:
- AddRequestParameter=foo, bar-{
segment}
Add parameters name=foo,value=bar-{segment}
3.3 The AddResponseHeader GatewayFilter Factory
spring:
cloud:
gateway:
routes:
- id: add_response_header_route
uri: https://example.org
predicates:
- Host: {
segment}.myhost.org
filters:
- AddResponseHeader=foo, bar-{
segment}
Add return header information name=foo,value=bar-{segment}
3.4 The DedupeResponseHeader GatewayFilter Factory
spring:
cloud:
gateway:
routes:
- id: dedupe_response_header_route
uri: https://example.org
filters:
- DedupeResponseHeader=Access-Control-Allow-Credentials Access-Control-Allow-Origin
Duplicate response headers will be removed when both gateway CROS and downstream response headers have Access-Control-Allow-Credentials and Access-Control-Allow-Origin
3.5 Spring Cloud CircuitBreaker GatewayFilter Factory
Use Spring Cloud CircuitBreaker's API to wrap gateway routes into circuit breakers. Spring Cloud CircuitBreaker supports multiple libraries for use with Spring Cloud Gateway. For example, Resilience4J.
To enable the Spring Cloud CircuitBreaker filter, you need to introduce spring-cloud-starter-circuitbreaker-reactor-resilience4j. The following is a configuration example
spring:
cloud:
gateway:
routes:
- id: circuitbreaker_route
uri: lb://backing-service:8088
predicates:
- Path=/consumingServiceEndpoint
filters:
- name: CircuitBreaker
args:
name: myCircuitBreaker
fallbackUri: forward:/inCaseOfFailureUseThis
- RewritePath=/consumingServiceEndpoint, /backingServiceEndpoint
RewritePath means rewriting the /consumingServiceEndpoint path to /backingServiceEndpoint
fallbackUri before requesting, that is, requests after circuit breaker need to jump to this path. This path can be provided by the gateway itself. For example: the gateway can provide a Controller with the path /inCaseOfFailureUseThis
is how the java code is written:
@Bean
public RouteLocator routes(RouteLocatorBuilder builder) {
return builder.routes()
.route("circuitbreaker_route", r -> r.path("/consumingServiceEndpoint")
.filters(f -> f.circuitBreaker(c -> c.name("myCircuitBreaker").fallbackUri("forward:/inCaseOfFailureUseThis"))
.rewritePath("/consumingServiceEndpoint", "/backingServiceEndpoint")).uri("lb://backing-service:8088")
.build();
}
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
This example is to jump to the /fallback path after the fuse is broken. The /fallback path happens to be provided by another service (http://localhost:9994)
3.6 The FallbackHeaders GatewayFilter Factory
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
The FallbackHeaders GatewayFilter Factory
In this example, after an exception occurs while running circuit breaker, the request will be forwarded to /fallback at http://localhost:9994. Exception type, message, etc. are added to the request header through the FallbackHeaders filter.
The names of headers can be overridden in the configuration by setting the parameter values listed below.
executionExceptionTypeHeaderName ("Execution-Exception-Type")
executionExceptionMessageHeaderName ("Execution-Exception-Message")
rootCauseExceptionTypeHeaderName ("Root-Cause-Exception-Type")
rootCauseExceptionMessageHeaderName ("Root-Cause-Exception-Message")
3.7 The MapRequestHeader GatewayFilter Factory
Receives two parameters, namely fromHeader and toHeader. It creates a new header (toHeader) and extracts the value from fromHeader. If the input header does not exist, the filter will not be executed. If the new header already exists, then it will be appended with the new value. As follows:
spring:
cloud:
gateway:
routes:
- id: map_request_header_route
uri: https://example.org
filters:
- MapRequestHeader=Blue, X-Request-Red
This example will add an X-Request-Red: header to the downstream request, with the value being the incoming HTTP request Blue value.
3.8 The PrefixPath GatewayFilter Factory
Receive a parameter prefix
spring:
cloud:
gateway:
routes:
- id: prefixpath_route
uri: https://example.org
filters:
- PrefixPath=/mypath
This example will prefix all matching request paths with /mypath, so when /hello is requested, it will be sent to /mypath/hello.
3.9 The PreserveHostHeader GatewayFilter Factory
spring:
cloud:
gateway:
routes:
- id: preserve_host_route
uri: https://example.org
filters:
- PreserveHostHeader
This filtering factory receives no parameters. After setting this Filter, the GatewayFilter will not use the host header determined by the HTTP client, but will send the original host header.
For example, the host header of the gateway is localhost:8080, and the host header of the downstream service is 192.168.1.11:8080. What is returned here is the host of the gateway, that is, localhost:8080.
3.10 The RequestRateLimiter GatewayFilter Factory
This filter uses RateLimiter to determine whether to allow the request to continue executing. If execution is not allowed to continue, HTTP 429 - Too
Many Requests is returned (by default).
This filter can be configured with an optional keyResolver parameter and rate limiter parameter.
keyResolver is an implementation class of KeyResolver. In the configuration, use SpEL to reference the bean by name. #{@myKeyResolver} is
a SpEL expression that references the bean named 'myKeyResolver'.
public interface KeyResolver {
Mono<String> resolve(ServerWebExchange exchange);
}
The KeyResolver interface allows the use of pluggable strategies to derive keys that limit requests. In future milestone releases, there will be some KeyResolver implementations.
The default implementation of KeyResolver is PrincipalNameKeyResolver, which retrieves the Principal from ServerWebExchange and calls Principal.getName().
By default, if the KeyResolver does not obtain the key, the request will be rejected. You can adjust it with the following settings:
spring.cloud.gateway.filter.request-rate-limiter.deny-empty-key (true or false)
spring.cloud.gateway.filter.request-rate-limiter.empty-key-status-code
RequestRateLimiter cannot be configured using "shortcut". The following configuration is invalid:
# INVALID SHORTCUT CONFIGURATION
spring.cloud.gateway.routes[0].filters[0]=RequestRateLimiter=2, 2, #{@userkeyresolver}
3.10.1 Redis RateLimiter (demo)
Redis implementation is based on Stripe. It needs to introduce the spring-boot-starter-data-redis-reactive dependency.
The algorithm used is Token Bucket Algorithm.
The redis-rate-limiter.replenishRate configuration is how many requests you allow users to perform per second without discarding any requests. This is the filling rate of the token bucket.
The redis-rate-limiter.burstCapacity configuration is the maximum number of requests that users are allowed to perform in one second. This is the number of tokens that the token bucket can hold. Setting this value to 0 will block all requests.
redis-rate-limiter.requestedTokens configures the number of tokens required for a request. The number of tokens extracted from the token bucket for each request. The default is 1.
Achieve a stable rate by setting the same value in replenishRate and burstCapacity. Temporary bursts of traffic can be allowed by setting burstCapacity higher than replenishRate. In this case, the rate limiter needs to allow some time between bursts (according to replenishRate), because two consecutive bursts will cause requests to be lost (HTTP 429 - Too Many Requests). The following list configures a redis-rate-limiter:
For example: replenishRate=1, requestedTokens=60 and burstCapacity=60 will be limited to 1 request/min.
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
Configure a KeyResolver
@Bean
KeyResolver userKeyResolver() {
return exchange -> Mono.just(exchange.getRequest().getQueryParams().getFirst("user"));
}
This defines a limit of 10 requests per user. 20 bursts are allowed, but only 10 requests are available the next second. KeyResolver is a simple
tool for obtaining user request parameters (note: not recommended for production).
The rate limiter can also be defined as an implementation bean of the RateLimiter interface. In the configuration, reference the bean by name using SpEL. #
{@myRateLimiter} is a SpEL expression that references the bean named myRateLimiter.
spring:
cloud:
gateway:
routes:
- id: requestratelimiter_route
uri: https://example.org
filters:
- name: RequestRateLimiter
args:
rate-limiter: "#{@myRateLimiter}"
key-resolver: "#{@userKeyResolver}"
3.11 The RedirectTo GatewayFilter Factory
Receives two parameters: status and url.
status is a 300 redirect HTTP code, such as 301. The url should be a valid URL and the value is the value of the Location header.
For relative paths, uri: no://op should be used as the route definition
spring:
cloud:
gateway:
routes:
- id: prefixpath_route
uri: https://example.org
filters:
- RedirectTo=302, https://acme.org
This example will send a 302 redirect status code to Location: https://acme.org
3.12 The RemoveRequestHeader GatewayFilter Factory
spring:
cloud:
gateway:
routes:
- id: removerequestheader_route
uri: https://example.org
filters:
- RemoveRequestHeader=X-Request-Foo
Delete request header:X-Request-Foo
3.13 RemoveResponseHeader GatewayFilter Factory
spring:
cloud:
gateway:
routes:
- id: removeresponseheader_route
uri: https://example.org
filters:
- RemoveResponseHeader=X-Response-Foo
Delete return header:X-Response-Foo
3.14 The RemoveRequestParameter GatewayFilter Factory
spring:
cloud:
gateway:
routes:
- id: removerequestparameter_route
uri: https://example.org
filters:
- RemoveRequestParameter=red
Delete request parameters
3.15 The RewritePath GatewayFilter Factory
spring:
cloud:
gateway:
routes:
- id: rewritepath_route
uri: https://example.org
predicates:
- Path=/red/**
filters:
- RewritePath=/red(?<segment>/?.*), $\{
segment}
For /red/blue request paths, will be replaced with /blue before being sent downstream. Because of the YAML specification, $ must be replaced with $\
3.16 RewriteLocationResponseHeader GatewayFilter Factory
This filter modifies the value of the Location response header and is often used to remove some sensitive information. The received parameters are:
stripVersionMode, locationHeaderName, hostValue, protocolsRegex
spring:
cloud:
gateway:
routes:
- id: rewritelocationresponseheader_route
uri: http://example.org
filters:
- RewriteLocationResponseHeader=AS_IN_REQUEST, Location, ,
The example shows that a POST request api.example.com/some/object/name, the value of the Location response header is object-
service.prod.example.net/v2/some/object/id will be rewritten to api.example .com/some/object/id .
The stripVersionMode parameter has the following values: NEVER_STRIP, AS_IN_REQUEST (default), and ALWAYS_STRIP.
NEVER_STRIP: The original request does not contain the version, and the version will not be removed.
AS_IN_REQUEST: The original request does not contain the version, and the version will be removed from the response header.
ALWAYS_STRIP: The version will always be removed.
hostValue parameter: If this value is provided, it will be used to replace host:port. The value of the Location header in the response. If it is empty,
the header value named Host in the request is used .
The protocolsRegex parameter is a valid regular string. If there is no match, the filter does not execute. The default value is http | https | ftp | ftps
3.17 The RewriteResponseHeader GatewayFilter Factory
spring:
cloud:
gateway:
routes:
- id: rewriteresponseheader_route
uri: https://example.org
filters:
- RewriteResponseHeader=X-Response-Red, , password=[^&]+, password=***
After the downstream response returns to the gateway, this example will set the value of the /42?user=ford&password=omg!what&flag=true header to /42?user=ford&password=***&flag=true
. You must use $\ instead of $
3.18 The SaveSession GatewayFilter Factory
SaveSession GatewayFilter Factory forces a WebSession::save operation before forwarding the call downstream.
This is particularly useful when using something like Spring Session, where you need to ensure that the session state is saved before making the forward call
spring:
cloud:
gateway:
routes:
- id: save_session
uri: https://example.org
predicates:
- Path=/foo/**
filters:
- SaveSession
This is important if you wish to integrate Spring Security with Spring Session and ensure that security information is passed downstream
3.19 The SecureHeaders GatewayFilter Factory
SecureHeaders GatewayFilter Factory adds many headers in the response.
Added the following headers (default)
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)
Use the spring.cloud.gateway.filter.secure-headers configuration to change the default value
xss-protection-header
strict-transport-security
x-frame-options
x-content-type-options
referrer-policy
content-security-policy
x-down-options
x-permitted-cross-domain-policies
Use spring.cloud.gateway.filter.secure-headers.disable to disable the default value, separated by commas in all lowercase letters
spring.cloud.gateway.filter.secure-headers.disable=x-frame-options,strict-transport-security
3.20 The SetPath GatewayFilter Factory
SetPath GatewayFilter Factory takes a template path parameter. It provides a simple way
to manipulate request paths by allowing templated segments of the path. Use URI templates in Spring Framework to allow multiple matching segments
spring:
cloud:
gateway:
routes:
- id: setpath_route
uri: https://example.org
predicates:
- Path=/red/{
segment}
filters:
- SetPath=/{
segment}
As shown above: requesting /red/blue will set the path to /blue when requesting downstream
3.21 The SetRequestHeader GatewayFilter Factory
spring:
cloud:
gateway:
routes:
- id: setrequestheader_route
uri: https://example.org
filters:
- SetRequestHeader=X-Request-Red, Blue
This GatewayFilter will replace all headers with the given name instead of adding them. Therefore, the request header will
be set from X-Request-Red:1234 to X-Request-Red:Blue.
SetRequestHeader allows the use of path or host URI variables
spring:
cloud:
gateway:
routes:
- id: setrequestheader_route
uri: https://example.org
predicates:
- Host: {
segment}.myhost.org
filters:
- SetRequestHeader=foo, bar-{
segment}
3.22 The SetResponseHeader GatewayFilter Factory
spring:
cloud:
gateway:
routes:
- id: setresponseheader_route
uri: https://example.org
filters:
- SetResponseHeader=X-Response-Red, Blue
This GatewayFilter will replace all headers with the given name instead of adding them. The downstream response header X-Response-Red:1234
will be replaced by X-Response-Red:Blue.
SetResponseHeader also uses the URI variable of path or host
spring:
cloud:
gateway:
routes:
- id: setresponseheader_route
uri: https://example.org
predicates:
- Host: {
segment}.myhost.org
filters:
- SetResponseHeader=foo, bar-{
segment}
3.23 The SetStatus GatewayFilter Factory
Receives a parameter status, which must be an available Spring HttpStatus value, which can be an integer or an enumerated string.
spring:
cloud:
gateway:
routes:
- id: setstatusstring_route
uri: https://example.org
filters:
- SetStatus=BAD_REQUEST
- id: setstatusint_route
uri: https://example.org
filters:
- SetStatus=401
This example sets the HTTP status response header to 401.
Use SetStatus to return the original HTTP status code in the proxy request in the response. Configure as follows to add the header to the response
spring:
cloud:
gateway:
set-status:
original-status-header-name: original-http-status
3.24 The StripPrefix GatewayFilter Factory
Receives a parts parameter. The parts parameter indicates the number of sections in the path to be removed from the request before sending it downstream.
spring:
cloud:
gateway:
routes:
- id: nameRoot
uri: https://nameservice
predicates:
- Path=/name/**
filters:
- StripPrefix=2
This example shows that when the gateway sends a /name/blue/red request, the actual downstream request address is nameservice/red
3.25 The Retry GatewayFilter Factory
Retry GatewayFilter Factory uses the retry component of reactor-addons to retry and supports the following parameters:
retries:应尝试的重试次数
statuses:应尝试的HTTP状态码
methods:应尝试的HTTP⽅法
series:应尝试的series状态码, org.springframework.http.HttpStatus.Series
exceptions:应尝试的异常列表
backoff:配置指数退避重试。根据 firstBackoff * (factor ^ n) 进⾏指数重试, maxBackoff 限制最⼤
Backoff retry, if basedOnPreviousValue is true, the backoff index calculation uses prevBackoff * factor.
The default value of the Retry filter is configured as follows:
retries: 3 times
series: 5XX series
methods: GET method
exceptions: IOException and TimeoutException
backoff: disabled
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
When a retry filter is used with any HTTP request with a body, the body will be cached.
The body is cached in ServerWebExchangeUtils.CACHED_REQUEST_BODY_ATTR defined in the request . The object type is: org.springframework.core.io.buffer.DataBuffer
3.26 The RequestSize GatewayFilter Factory
When the request size is larger than the allowed limit, the RequestSize GatewayFilter Factory can limit the request from reaching the downstream service. The filter takes
RequestSize as parameter, which is the allowed size limit that defines the request (in bytes)
spring:
cloud:
gateway:
routes:
- id: request_size_route
uri: http://localhost:8080/upload
predicates:
- Path=/upload
filters:
- name: RequestSize
args:
maxSize: 5000000
When a request is rejected due to size, RequestSize GatewayFilter Factory sets the response status to 413 Payload Too Large
with additional header errorMessage errorMessage
Request :
size is larger than permissible limit. Request size is 6.0 MB where permissible limit is 5.0 MB
3.27 The SetRequestHost GatewayFilter Factory
spring:
cloud:
gateway:
routes:
- id: set_request_host_header_route
uri: http://localhost:8080/headers
predicates:
- Path=/headers
filters:
- name: SetRequestHost
args:
host: example.org
This example indicates using example.org instead of the value of the host header.
3.28 Modify a Request Body GatewayFilter Factory
This filter can be used to modify the request body before it is sent downstream by the gateway
@Bean
public RouteLocator routes(RouteLocatorBuilder builder) {
return builder.routes()
//此过滤器可⽤于在请求主体被⽹关发送到下游之前对其进⾏修改
.route("rewrite_request_obj", r -> r.host("*.rewriterequestobj.org")
.filters(f -> f.prefixPath("/httpbin")
.modifyRequestBody(String.class, Hello.class, MediaType.APPLICATION_JSON_VALUE,
(exchange, s) -> return Mono.just(new Hello(s.toUpperCase())))).uri(uri))
.build();
}
static class Hello {
String message;
public Hello() {
}
public Hello(String message) {
this.message = message;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
3.29 Modify a Response Body GatewayFilter Factory
This filter can be used to modify the response body before sending it back to the client
@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();
}
4. Set Default Filters
You can use spring.cloud.gateway.default-filters as filters for all routes. This configuration receives a filter list, as follows
spring:
cloud:
gateway:
default-filters:
- AddResponseHeader=X-Response-Default-Red, Default-Blue
- PrefixPath=/httpbin
5. Questions
-
Question 1: If there are only filters under routes and no predicates, what will be the effect? Does this filter intercept all requests or none?
-
Question 2: predicates and filters are plural, which means multiple predicates and multiple filters can be configured. How to configure them?
The following example shows a configuration of two filters, using circuit breakers and rewriting path filters.
spring:
cloud:
gateway:
routes:
- id: circuitbreaker_route
uri: lb://backing-service:8088
predicates:
- Path=/consumingServiceEndpoint
filters:
- name: CircuitBreaker
args:
name: myCircuitBreaker
fallbackUri: forward:/inCaseOfFailureUseThis
- RewritePath=/consumingServiceEndpoint, /backingServiceEndpoint