Route filters allow the modification of the incoming HTTP request or outgoing HTTP response in some manner. Route filters are scoped to a particular route. Spring Cloud Gateway includes many built-in GatewayFilter Factories.
NOTE For more detailed examples on how to use any of the following filters, take a look at the unit tests.
The AddRequestHeader
GatewayFilter Factory takes a name
and value
parameter.
application.yml.
spring: cloud: gateway: routes: - id: add_request_header_route uri: https://example.org filters: - AddRequestHeader=X-Request-Foo, Bar
This will add X-Request-Foo:Bar
header to the downstream request’s headers for all matching requests.
AddRequestHeader 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.
application.yml.
spring: cloud: gateway: routes: - id: add_request_header_route uri: https://example.org predicates: - Path=/foo/{segment} filters: - AddRequestHeader=X-Request-Foo, Bar-{segment}
The AddRequestParameter
GatewayFilter Factory takes a name
and value
parameter.
application.yml.
spring: cloud: gateway: routes: - id: add_request_parameter_route uri: https://example.org filters: - AddRequestParameter=foo, bar
This will add foo=bar
to the downstream request’s query string for all matching requests.
AddRequestParameter 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.
application.yml.
spring: cloud: gateway: routes: - id: add_request_parameter_route uri: https://example.org predicates: - Host: {segment}.myhost.org filters: - AddRequestParameter=foo, bar-{segment}
The AddResponseHeader
GatewayFilter Factory takes a name
and value
parameter.
application.yml.
spring: cloud: gateway: routes: - id: add_response_header_route uri: https://example.org filters: - AddResponseHeader=X-Response-Foo, Bar
This will add X-Response-Foo:Bar
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 will be expanded at runtime.
application.yml.
spring: cloud: gateway: routes: - id: add_response_header_route uri: https://example.org predicates: - Host: {segment}.myhost.org filters: - AddResponseHeader=foo, bar-{segment}
The DedupeResponseHeader
GatewayFilter Factory takes a name
parameter and an optional strategy
parameter. name
can contain a list of header names, space separated.
application.yml.
spring: cloud: gateway: routes: - id: dedupe_response_header_route uri: https://example.org filters: - DedupeResponseHeader=Access-Control-Allow-Credentials Access-Control-Allow-Origin
This will remove 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 add them.
The DedupeResponseHeader filter also accepts an optional strategy
parameter. The accepted values are RETAIN_FIRST
(default), RETAIN_LAST
, and RETAIN_UNIQUE
.
Hystrix is a library from Netflix that implements the circuit breaker pattern.
The Hystrix
GatewayFilter allows you to introduce circuit breakers to your gateway routes, protecting your services from cascading failures and allowing you to provide fallback responses in the event of downstream failures.
To enable Hystrix
GatewayFilters in your project, add a dependency on spring-cloud-starter-netflix-hystrix
from Spring Cloud Netflix.
The Hystrix
GatewayFilter Factory requires a single name
parameter, which is the name of the HystrixCommand
.
application.yml.
spring: cloud: gateway: routes: - id: hystrix_route uri: https://example.org filters: - Hystrix=myCommandName
This wraps the remaining filters in a HystrixCommand
with command name myCommandName
.
The Hystrix filter can also accept an optional fallbackUri
parameter. Currently, only forward:
schemed URIs are supported. If the fallback is called, the request will be forwarded to the controller matched by the URI.
application.yml.
spring: cloud: gateway: routes: - id: hystrix_route uri: lb://backing-service:8088 predicates: - Path=/consumingserviceendpoint filters: - name: Hystrix args: name: fallbackcmd fallbackUri: forward:/incaseoffailureusethis - RewritePath=/consumingserviceendpoint, /backingserviceendpoint
This will forward to the /incaseoffailureusethis
URI when the Hystrix fallback is called. Note that this example also demonstrates (optional) Spring Cloud Netflix Ribbon load-balancing via the lb
prefix on the destination URI.
The primary scenario is to use the fallbackUri
to an internal controller or handler within the gateway app.
However, it is also possible to reroute the request to a controller or handler in an external application, like so:
application.yml.
spring: cloud: gateway: routes: - id: ingredients uri: lb://ingredients predicates: - Path=//ingredients/** filters: - name: Hystrix args: name: fetchIngredients fallbackUri: forward:/fallback - id: ingredients-fallback uri: http://localhost:9994 predicates: - Path=/fallback
In this example, there is no fallback
endpoint or handler in the gateway application, however, there is one in another
app, registered under http://localhost:9994
.
In case of the request being forwarded to fallback, the Hystrix Gateway filter also provides the Throwable
that has
caused it. It’s added to the ServerWebExchange
as the
ServerWebExchangeUtils.HYSTRIX_EXECUTION_EXCEPTION_ATTR
attribute that can be used when
handling the fallback within the gateway app.
For the external controller/ handler scenario, headers can be added with exception details. You can find more information on it in the FallbackHeaders GatewayFilter Factory section.
Hystrix settings (such as timeouts) can be configured with global defaults or on a route by route basis using application properties as explained on the Hystrix wiki.
To set a 5 second timeout for the example route above, the following configuration would be used:
application.yml.
hystrix.command.fallbackcmd.execution.isolation.thread.timeoutInMilliseconds: 5000
The FallbackHeaders
factory allows you to add Hystrix execution exception details in headers of a request forwarded to
a fallbackUri
in an external application, like in the following scenario:
application.yml.
spring: cloud: gateway: routes: - id: ingredients uri: lb://ingredients predicates: - Path=//ingredients/** filters: - name: Hystrix args: name: fetchIngredients fallbackUri: forward:/fallback - id: ingredients-fallback uri: http://localhost:9994 predicates: - Path=/fallback filters: - name: FallbackHeaders args: executionExceptionTypeHeaderName: Test-Header
In this example, after an execution exception occurs while running the HystrixCommand
, the request will be forwarde to
the fallback
endpoint or handler in an app running on localhost:9994
. The headers with the exception type, message
and -if available- root cause exception type and message will be added to that request by the FallbackHeaders
filter.
The names of the headers can be overwritten in the config by setting the values of the arguments listed below, along with their default values:
executionExceptionTypeHeaderName
("Execution-Exception-Type"
)executionExceptionMessageHeaderName
("Execution-Exception-Message"
)rootCauseExceptionTypeHeaderName
("Root-Cause-Exception-Type"
)rootCauseExceptionMessageHeaderName
("Root-Cause-Exception-Message"
)You can find more information on how Hystrix works with Gateway in the Hystrix GatewayFilter Factory section.
The MapRequestHeader
GatewayFilter Facstory 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 then the filter has no impact. If the new named header already exists then it’s values will be augmented with the new values.
application.yml.
spring: cloud: gateway: routes: - id: map_request_header_route uri: https://example.org filters: - MapRequestHeader=Bar, X-Request-Foo
This will add X-Request-Foo:<values>
header to the downstream request’s with updated values from the incoming http request Bar
header.
The PrefixPath
GatewayFilter Factory takes a single prefix
parameter.
application.yml.
spring: cloud: gateway: routes: - id: prefixpath_route uri: https://example.org filters: - PrefixPath=/mypath
This will prefix /mypath
to the path of all matching requests. So a request to /hello
, would be sent to /mypath/hello
.
The PreserveHostHeader
GatewayFilter Factory has no parameters. This filter, sets a request attribute that the routing filter will inspect to determine if the original host header should be sent, rather than the host header determined by the http client.
application.yml.
spring: cloud: gateway: routes: - id: preserve_host_route uri: https://example.org filters: - PreserveHostHeader
The RequestRateLimiter
GatewayFilter Factory is 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 (see below).
keyResolver
is a bean that implements the KeyResolver
interface. In configuration, reference the bean by name using SpEL. #{@myKeyResolver}
is a SpEL expression referencing a bean with the name myKeyResolver
.
KeyResolver.java.
public interface KeyResolver { Mono<String> resolve(ServerWebExchange exchange); }
The KeyResolver
interface allows pluggable strategies to derive the key for limiting requests. In future milestones, 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 will be denied. This behavior can be adjust with 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 via the "shortcut" notation. The example below is invalid |
application.properties.
# INVALID SHORTCUT CONFIGURATION spring.cloud.gateway.routes[0].filters[0]=RequestRateLimiter=2, 2, #{@userkeyresolver}
The redis implementation is based off of work done at Stripe. It requires the use of the spring-boot-starter-data-redis-reactive
Spring Boot starter.
The algorithm used is the Token Bucket Algorithm.
The redis-rate-limiter.replenishRate
is how many requests per second do you want a user to be allowed to do, without any dropped requests. This is the rate that the token bucket is filled.
The redis-rate-limiter.burstCapacity
is the maximum number of requests a user is allowed to do in a single second. This is the number of tokens the token bucket can hold. Setting this value to zero will block all requests.
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 2 consecutive bursts will result in dropped requests (HTTP 429 - Too Many Requests
).
application.yml.
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
Config.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 the next second only 10 requests will be available. The KeyResolver
is a simple one that gets the user
request parameter (note: this is not recommended for production).
A rate limiter can also be defined as a bean implementing the RateLimiter
interface. In configuration, reference the bean by name using SpEL. #{@myRateLimiter}
is a SpEL expression referencing a bean with the name myRateLimiter
.
application.yml.
spring: cloud: gateway: routes: - id: requestratelimiter_route uri: https://example.org filters: - name: RequestRateLimiter args: rate-limiter: "#{@myRateLimiter}" key-resolver: "#{@userKeyResolver}"
The RedirectTo
GatewayFilter Factory takes a status
and a url
parameter. The status should be a 300 series redirect http code, such as 301. The url should be a valid url. This will be the value of the Location
header.
application.yml.
spring: cloud: gateway: routes: - id: prefixpath_route uri: https://example.org filters: - RedirectTo=302, https://acme.org
This will send a status 302 with a Location:https://acme.org
header to perform a redirect.
The RemoveRequestHeader
GatewayFilter Factory takes a name
parameter. It is the name of the header to be removed.
application.yml.
spring: cloud: gateway: routes: - id: removerequestheader_route uri: https://example.org filters: - RemoveRequestHeader=X-Request-Foo
This will remove the X-Request-Foo
header before it is sent downstream.
The RemoveResponseHeader
GatewayFilter Factory takes a name
parameter. It is the name of the header to be removed.
application.yml.
spring: cloud: gateway: routes: - id: removeresponseheader_route uri: https://example.org filters: - RemoveResponseHeader=X-Response-Foo
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 that you may
want to do so. In addition you can configure this filter once using spring.cloud.gateway.default-filters
and have it applied to all routes.
The RewritePath
GatewayFilter Factory takes a path regexp
parameter and a replacement
parameter. This uses Java regular expressions for a flexible way to rewrite the request path.
application.yml.
spring: cloud: gateway: routes: - id: rewritepath_route uri: https://example.org predicates: - Path=/foo/** filters: - RewritePath=/foo(?<segment>/?.*), $\{segment}
For a request path of /foo/bar
, this will set the path to /bar
before making the downstream request. Notice the $\
which is replaced with $
because of the YAML spec.
The RewriteLocationResponseHeader
GatewayFilter Factory modifies the value of Location
response header, usually to get rid of backend specific details. It takes stripVersionMode
, locationHeaderName
, hostValue
, and protocolsRegex
parameters.
application.yml.
spring: cloud: gateway: routes: - id: rewritelocationresponseheader_route uri: http://example.org filters: - RewriteLocationResponseHeader=AS_IN_REQUEST, Location, ,
For example, for a request POST https://api.example.com/some/object/name
, Location
response header value https://object-service.prod.example.net/v2/some/object/id
will be rewritten as https://api.example.com/some/object/id
.
Parameter stripVersionMode
has the following possible values: NEVER_STRIP
, AS_IN_REQUEST
(default), ALWAYS_STRIP
.
NEVER_STRIP
- Version will not be stripped, even if the original request path contains no versionAS_IN_REQUEST
- Version will be stripped only if the original request path contains no versionALWAYS_STRIP
- Version will be stripped, even if the original request path contains versionParameter hostValue
, if provided, will be used to replace the host:port
portion of the response Location
header. If not provided, the value of the Host
request header will be used.
Parameter protocolsRegex
must be a valid regex String
, against which the protocol name will be matched. If not matched, the filter will do nothing. Default is http|https|ftp|ftps
.
The RewriteResponseHeader
GatewayFilter Factory takes name
, regexp
, and replacement
parameters. It uses Java regular expressions for a flexible way to rewrite the response header value.
application.yml.
spring: cloud: gateway: routes: - id: rewriteresponseheader_route uri: https://example.org filters: - RewriteResponseHeader=X-Response-Foo, , password=[^&]+, password=***
For a header value of /42?user=ford&password=omg!what&flag=true
, it will be set to /42?user=ford&password=***&flag=true
after making the downstream request. Please use $\
to mean $
because of the YAML spec.
The SaveSession GatewayFilter Factory forces a WebSession::save
operation before forwarding the call downstream. This is of particular use when
using something like Spring Session with a lazy data store and need to ensure the session state has been saved before making the forwarded call.
application.yml.
spring: cloud: gateway: routes: - id: save_session uri: https://example.org predicates: - Path=/foo/** filters: - SaveSession
If you are integrating Spring Security with Spring Session, and want to ensure security details have been forwarded to the remote process, this is critical.
The SecureHeaders
GatewayFilter Factory adds a number of headers to the response at the recommendation from this blog post.
The following headers are added (along with default values):
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:
Property to change:
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 property spring.cloud.gateway.filter.secure-headers.disable
with comma separated values.
Note | |
---|---|
Need use lowercase and full name of secure headers. |
The following values can use:
x-xss-protection
strict-transport-security
x-frame-options
x-content-type-options
referrer-policy
content-security-policy
x-download-options
x-permitted-cross-domain-policies
Example: spring.cloud.gateway.filter.secure-headers.disable=x-frame-options,strict-transport-security
The SetPath
GatewayFilter Factory 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.
application.yml.
spring: cloud: gateway: routes: - id: setpath_route uri: https://example.org predicates: - Path=/foo/{segment} filters: - SetPath=/{segment}
For a request path of /foo/bar
, this will set the path to /bar
before making the downstream request.
The SetRequestHeader
GatewayFilter Factory takes name
and value
parameters.
application.yml.
spring: cloud: gateway: routes: - id: setrequestheader_route uri: https://example.org filters: - SetRequestHeader=X-Request-Foo, Bar
This GatewayFilter replaces all headers with the given name, rather than adding. So if the downstream server responded with a X-Request-Foo:1234
, this would be replaced with X-Request-Foo:Bar
, 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 will be expanded at runtime.
application.yml.
spring: cloud: gateway: routes: - id: setrequestheader_route uri: https://example.org predicates: - Host: {segment}.myhost.org filters: - SetRequestHeader=foo, bar-{segment}
The SetResponseHeader
GatewayFilter Factory takes name
and value
parameters.
application.yml.
spring: cloud: gateway: routes: - id: setresponseheader_route uri: https://example.org filters: - SetResponseHeader=X-Response-Foo, Bar
This GatewayFilter replaces all headers with the given name, rather than adding. So if the downstream server responded with a X-Response-Foo:1234
, this would be replaced with X-Response-Foo:Bar
, 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.
application.yml.
spring: cloud: gateway: routes: - id: setresponseheader_route uri: https://example.org predicates: - Host: {segment}.myhost.org filters: - SetResponseHeader=foo, bar-{segment}
The SetStatus
GatewayFilter Factory takes a single status
parameter. It must be a valid Spring HttpStatus
. It may be the integer value 404
or the string representation of the enumeration NOT_FOUND
.
application.yml.
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
In either case, the HTTP status of the response will be set to 401.
The StripPrefix GatewayFilter Factory takes one paramter, parts
. The parts
parameter indicated the number of parts in the path to strip from the request before sending it downstream.
application.yml.
spring: cloud: gateway: routes: - id: nameRoot uri: http://nameservice predicates: - Path=/name/** filters: - StripPrefix=2
When a request is made through the gateway to /name/bar/foo
the request made to nameservice
will look like http://nameservice/foo
.
The Retry
GatewayFilter Factory support following set of parameters:
retries
: the number of retries that should be attemptedstatuses
: the HTTP status codes that should be retried, represented using org.springframework.http.HttpStatus
methods
: the HTTP methods that should be retried, represented using org.springframework.http.HttpMethod
series
: the series of status codes to be retried, represented using org.springframework.http.HttpStatus.Series
exceptions
: list of exceptions thrown that should be retriedbackoff
: 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 will be limited to maxBackoff
.
If basedOnPreviousValue
is true, backoff will be calculated using prevBackoff * factor
.The following defaults are configured for Retry
filter if enabled:
retries
— 3 timesseries
— 5XX seriesmethods
— GET methodexceptions
— IOException
and TimeoutException
backoff
— disabledapplication.yml.
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 |
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 |
The RequestSize
GatewayFilter Factory can restrict a request from reaching the downstream service , when the request size is greater than the permissible limit. The filter takes a maxSize
parameter which is the permissible size limit of the request. 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.
application.yml.
spring: cloud: gateway: routes: - id: request_size_route uri: http://localhost:8080/upload predicates: - Path=/upload filters: - name: RequestSize args: maxSize: 5000000
The RequestSize GatewayFilter Factory set the response status as 413 Payload Too Large
with a additional header errorMessage
when the Request is rejected due to size. Following is an example of such an errorMessage
.
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 will be set to 5 MB if not provided as filter argument in route definition. |
This filter is considered BETA and the API may change in the future
The ModifyRequestBody
filter can be used to modify the request body before it is sent downstream by the Gateway.
Note | |
---|---|
This filter can only be configured using the Java DSL |
@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; } }
This filter is considered BETA and the API may change in the future
The ModifyResponseBody
filter can be used to modify the response body before it is sent back to the Client.
Note | |
---|---|
This filter can only be configured using the Java DSL |
@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(); }
If you would like to add a filter and apply it to all routes you can use spring.cloud.gateway.default-filters
.
This property takes a list of filters
application.yml.
spring: cloud: gateway: default-filters: - AddResponseHeader=X-Response-Default-Foo, Default-Bar - PrefixPath=/httpbin