Compare commits
12 Commits
Author | SHA1 | Date |
---|---|---|
sgibb | 9547e8d04b | 1 year ago |
sgibb | 68cf3f2b4f | 1 year ago |
sgibb | 804dcb88f8 | 1 year ago |
sgibb | e95504cf8a | 1 year ago |
sgibb | eef5ddacee | 1 year ago |
sgibb | 309abd4ba6 | 1 year ago |
sgibb | ff29a7f690 | 1 year ago |
sgibb | 2515d4474d | 1 year ago |
sgibb | bfb64d7d24 | 1 year ago |
sgibb | d2c6ccf690 | 1 year ago |
sgibb | 047de7e134 | 1 year ago |
sgibb | 5641092595 | 1 year ago |
82 changed files with 3554 additions and 3645 deletions
@ -0,0 +1,32 @@
@@ -0,0 +1,32 @@
|
||||
name: Deploy Docs |
||||
on: |
||||
push: |
||||
branches-ignore: [ gh-pages ] |
||||
tags: '**' |
||||
repository_dispatch: |
||||
types: request-build-reference # legacy |
||||
#schedule: |
||||
#- cron: '0 10 * * *' # Once per day at 10am UTC |
||||
workflow_dispatch: |
||||
permissions: |
||||
actions: write |
||||
jobs: |
||||
build: |
||||
runs-on: ubuntu-latest |
||||
# if: github.repository_owner == 'spring-cloud' |
||||
steps: |
||||
- name: Checkout |
||||
uses: actions/checkout@v3 |
||||
with: |
||||
ref: docs-build |
||||
fetch-depth: 1 |
||||
- name: Dispatch (partial build) |
||||
if: github.ref_type == 'branch' |
||||
env: |
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} |
||||
run: gh workflow run deploy-docs.yml -r $(git rev-parse --abbrev-ref HEAD) -f build-refname=${{ github.ref_name }} |
||||
- name: Dispatch (full build) |
||||
if: github.ref_type == 'tag' |
||||
env: |
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} |
||||
run: gh workflow run deploy-docs.yml -r $(git rev-parse --abbrev-ref HEAD) |
@ -0,0 +1,43 @@
@@ -0,0 +1,43 @@
|
||||
antora: |
||||
extensions: |
||||
- '@springio/antora-extensions/partial-build-extension' |
||||
- require: '@springio/antora-extensions/latest-version-extension' |
||||
- require: '@springio/antora-extensions/inject-collector-cache-config-extension' |
||||
- '@antora/collector-extension' |
||||
- '@antora/atlas-extension' |
||||
- require: '@springio/antora-extensions/root-component-extension' |
||||
root_component_name: 'cloud-gateway' |
||||
# FIXME: Run antora once using this extension to migrate to the Asciidoc Tabs syntax |
||||
# and then remove this extension |
||||
- require: '@springio/antora-extensions/tabs-migration-extension' |
||||
unwrap_example_block: always |
||||
save_result: true |
||||
site: |
||||
title: Spring Cloud Gateway |
||||
url: https://docs.spring.io/spring-cloud-gateway/reference/ |
||||
content: |
||||
sources: |
||||
- url: ./.. |
||||
branches: HEAD |
||||
start_path: docs |
||||
worktrees: true |
||||
asciidoc: |
||||
attributes: |
||||
page-stackoverflow-url: https://stackoverflow.com/tags/spring-cloud |
||||
page-pagination: '' |
||||
hide-uri-scheme: '@' |
||||
tabs-sync-option: '@' |
||||
chomp: 'all' |
||||
extensions: |
||||
- '@asciidoctor/tabs' |
||||
- '@springio/asciidoctor-extensions' |
||||
sourcemap: true |
||||
urls: |
||||
latest_version_segment: '' |
||||
runtime: |
||||
log: |
||||
failure_level: warn |
||||
format: pretty |
||||
ui: |
||||
bundle: |
||||
url: https://github.com/spring-io/antora-ui-spring/releases/download/v0.3.5/ui-bundle.zip |
@ -0,0 +1,12 @@
@@ -0,0 +1,12 @@
|
||||
name: cloud-gateway |
||||
version: true |
||||
title: spring-cloud-gateway |
||||
nav: |
||||
- modules/ROOT/nav.adoc |
||||
ext: |
||||
collector: |
||||
run: |
||||
command: ./mvnw --no-transfer-progress -B process-resources -Pdocs -pl docs -Dantora-maven-plugin.phase=none -Dgenerate-docs.phase=none -Dgenerate-readme.phase=none -Dgenerate-cloud-resources.phase=none -Dmaven-dependency-plugin-for-docs.phase=none -Dmaven-dependency-plugin-for-docs-classes.phase=none -DskipTests |
||||
local: true |
||||
scan: |
||||
dir: ./target/classes/antora-resources/ |
Before Width: | Height: | Size: 236 KiB After Width: | Height: | Size: 236 KiB |
Before Width: | Height: | Size: 27 KiB After Width: | Height: | Size: 27 KiB |
@ -0,0 +1,64 @@
@@ -0,0 +1,64 @@
|
||||
* xref:intro.adoc[] |
||||
* xref:spring-cloud-gateway.adoc[] |
||||
** xref:spring-cloud-gateway/starter.adoc[] |
||||
** xref:spring-cloud-gateway/glossary.adoc[] |
||||
** xref:spring-cloud-gateway/how-it-works.adoc[] |
||||
** xref:spring-cloud-gateway/configuring-route-predicate-factories-and-filter-factories.adoc[] |
||||
** xref:spring-cloud-gateway/request-predicates-factories.adoc[] |
||||
** xref:spring-cloud-gateway/gatewayfilter-factories.adoc[] |
||||
*** xref:spring-cloud-gateway/gatewayfilter-factories/the-addrequestheader-factory.adoc[] |
||||
*** xref:spring-cloud-gateway/gatewayfilter-factories/the-addrequestheadersifnotpresent-factory.adoc[] |
||||
*** xref:spring-cloud-gateway/gatewayfilter-factories/the-addrequestparameter-factory.adoc[] |
||||
*** xref:spring-cloud-gateway/gatewayfilter-factories/the-addresponseheader-factory.adoc[] |
||||
*** xref:spring-cloud-gateway/gatewayfilter-factories/circuitbreaker-filter-factory.adoc[] |
||||
*** xref:spring-cloud-gateway/gatewayfilter-factories/the-cacherequestbody-factory.adoc[] |
||||
*** xref:spring-cloud-gateway/gatewayfilter-factories/the-deduperesponseheader-factory.adoc[] |
||||
*** xref:spring-cloud-gateway/gatewayfilter-factories/fallback-headers.adoc[] |
||||
*** xref:spring-cloud-gateway/gatewayfilter-factories/the-jsontogrpc-factory.adoc[] |
||||
*** xref:spring-cloud-gateway/gatewayfilter-factories/local-cache-response-filter.adoc[] |
||||
*** xref:spring-cloud-gateway/gatewayfilter-factories/the-maprequestheader-factory.adoc[] |
||||
*** xref:spring-cloud-gateway/gatewayfilter-factories/the-modifyrequestbody-factory.adoc[] |
||||
*** xref:spring-cloud-gateway/gatewayfilter-factories/the-modifyresponsebody-factory.adoc[] |
||||
*** xref:spring-cloud-gateway/gatewayfilter-factories/the-prefixpath-factory.adoc[] |
||||
*** xref:spring-cloud-gateway/gatewayfilter-factories/the-preservehostheader-factory.adoc[] |
||||
*** xref:spring-cloud-gateway/gatewayfilter-factories/the-redirectto-factory.adoc[] |
||||
*** xref:spring-cloud-gateway/gatewayfilter-factories/removejsonattributesresponsebody-factory.adoc[] |
||||
*** xref:spring-cloud-gateway/gatewayfilter-factories/the-removerequestheader-factory.adoc[] |
||||
*** xref:spring-cloud-gateway/gatewayfilter-factories/the-removerequestparameter-factory.adoc[] |
||||
*** xref:spring-cloud-gateway/gatewayfilter-factories/the-removeresponseheader-factory.adoc[] |
||||
*** xref:spring-cloud-gateway/gatewayfilter-factories/the-requestheadersize-factory.adoc[] |
||||
*** xref:spring-cloud-gateway/gatewayfilter-factories/the-requestratelimiter-factory.adoc[] |
||||
*** xref:spring-cloud-gateway/gatewayfilter-factories/the-rewritelocationresponseheader-factory.adoc[] |
||||
*** xref:spring-cloud-gateway/gatewayfilter-factories/the-rewritepath-factory.adoc[] |
||||
*** xref:spring-cloud-gateway/gatewayfilter-factories/the-rewriteresponseheader-factory.adoc[] |
||||
*** xref:spring-cloud-gateway/gatewayfilter-factories/the-savesession-factory.adoc[] |
||||
*** xref:spring-cloud-gateway/gatewayfilter-factories/the-secureheaders-factory.adoc[] |
||||
*** xref:spring-cloud-gateway/gatewayfilter-factories/the-setpath-factory.adoc[] |
||||
*** xref:spring-cloud-gateway/gatewayfilter-factories/the-setrequestheader-factory.adoc[] |
||||
*** xref:spring-cloud-gateway/gatewayfilter-factories/the-setresponseheader-factory.adoc[] |
||||
*** xref:spring-cloud-gateway/gatewayfilter-factories/the-setstatus-factory.adoc[] |
||||
*** xref:spring-cloud-gateway/gatewayfilter-factories/the-stripprefix-factory.adoc[] |
||||
*** xref:spring-cloud-gateway/gatewayfilter-factories/the-retry-factory.adoc[] |
||||
*** xref:spring-cloud-gateway/gatewayfilter-factories/the-requestsize-factory.adoc[] |
||||
*** xref:spring-cloud-gateway/gatewayfilter-factories/the-setrequesthostheader-factory.adoc[] |
||||
*** xref:spring-cloud-gateway/gatewayfilter-factories/the-tokenrelay-factory.adoc[] |
||||
*** xref:spring-cloud-gateway/gatewayfilter-factories/default-filters.adoc[] |
||||
** xref:spring-cloud-gateway/global-filters.adoc[] |
||||
** xref:spring-cloud-gateway/httpheadersfilters.adoc[] |
||||
** xref:spring-cloud-gateway/tls-and-ssl.adoc[] |
||||
** xref:spring-cloud-gateway/configuration.adoc[] |
||||
** xref:spring-cloud-gateway/route-metadata-configuration.adoc[] |
||||
** xref:spring-cloud-gateway/http-timeouts-configuration.adoc[] |
||||
** xref:spring-cloud-gateway/fluent-java-routes-api.adoc[] |
||||
** xref:spring-cloud-gateway/the-discoveryclient-route-definition-locator.adoc[] |
||||
** xref:spring-cloud-gateway/reactor-netty-access-logs.adoc[] |
||||
** xref:spring-cloud-gateway/cors-configuration.adoc[] |
||||
** xref:spring-cloud-gateway/actuator-api.adoc[] |
||||
** xref:spring-cloud-gateway/troubleshooting.adoc[] |
||||
** xref:spring-cloud-gateway/developer-guide.adoc[] |
||||
** xref:spring-cloud-gateway/aot-and-native-image-support.adoc[] |
||||
** xref:spring-cloud-gateway/configuration-properties.adoc[] |
||||
* xref:spring-cloud-gateway-server-mvc.adoc[] |
||||
** xref:spring-cloud-gateway-server-mvc/starter.adoc[] |
||||
* xref:spring-cloud-gateway-proxy-exchange.adoc[] |
||||
* xref:appendix.adoc[] |
@ -1,8 +1,6 @@
@@ -1,8 +1,6 @@
|
||||
:doctype: book |
||||
:idprefix: |
||||
:idseparator: - |
||||
:toc: left |
||||
:toclevels: 4 |
||||
:tabsize: 4 |
||||
:numbered: |
||||
:sectanchors: |
@ -0,0 +1,21 @@
@@ -0,0 +1,21 @@
|
||||
:numbered!: |
||||
[appendix] |
||||
[[common-application-properties]] |
||||
= Common application properties |
||||
:page-section-summary-toc: 1 |
||||
|
||||
|
||||
Various properties can be specified inside your `application.properties` file, inside your `application.yml` file, or as command line switches. |
||||
This appendix provides a list of common Spring Cloud Gateway properties and references to the underlying classes that consume them. |
||||
|
||||
NOTE: Property contributions can come from additional jar files on your classpath, so you should not consider this an exhaustive list. |
||||
Also, you can define your own properties. |
||||
|
||||
[[observability]] |
||||
== Observability metadata |
||||
|
||||
include::partial$_metrics.adoc[] |
||||
|
||||
include::partial$_spans.adoc[] |
||||
|
||||
include::partial$_conventions.adoc[] |
@ -0,0 +1,6 @@
@@ -0,0 +1,6 @@
|
||||
[[configuration-properties]] |
||||
= Configuration Properties |
||||
|
||||
Below you can find a list of configuration properties. |
||||
|
||||
include::partial$_configprops.adoc[] |
@ -1,2 +1,5 @@
@@ -1,2 +1,5 @@
|
||||
[[spring-cloud-gateway-intro]] |
||||
= Introduction |
||||
// TODO: docs, rework intro for 4 modules |
||||
This project provides an API Gateway built on top of the Spring Ecosystem, including: Spring 6, Spring Boot 3 and Project Reactor. Spring Cloud Gateway aims to provide a simple, yet effective way to route to APIs and provide cross cutting concerns to them such as: security, monitoring/metrics, and resiliency. |
||||
|
@ -0,0 +1,72 @@
@@ -0,0 +1,72 @@
|
||||
[[proxy-exchange-gateway]] |
||||
= Proxy Exchange Gateway with Spring MVC or Webflux |
||||
|
||||
WARNING: The following describes an alternative style gateway. None of the Spring Cloud Gateway Server documentation applies to what follows. |
||||
|
||||
Spring Cloud Gateway provides a utility object called `ProxyExchange`. |
||||
You can use it inside a regular Spring web handler as a method parameter. |
||||
It supports basic downstream HTTP exchanges through methods that mirror the HTTP verbs. |
||||
With MVC, it also supports forwarding to a local handler through the `forward()` method. |
||||
To use the `ProxyExchange`, include the right module in your classpath (either `spring-cloud-gateway-mvc` or `spring-cloud-gateway-webflux`). |
||||
|
||||
The following MVC example proxies a request to `/test` downstream to a remote server: |
||||
|
||||
[source,java] |
||||
---- |
||||
@RestController |
||||
@SpringBootApplication |
||||
public class GatewaySampleApplication { |
||||
|
||||
@Value("${remote.home}") |
||||
private URI home; |
||||
|
||||
@GetMapping("/test") |
||||
public ResponseEntity<?> proxy(ProxyExchange<byte[]> proxy) throws Exception { |
||||
return proxy.uri(home.toString() + "/image/png").get(); |
||||
} |
||||
|
||||
} |
||||
---- |
||||
|
||||
The following example does the same thing with Webflux: |
||||
|
||||
[source,java] |
||||
---- |
||||
@RestController |
||||
@SpringBootApplication |
||||
public class GatewaySampleApplication { |
||||
|
||||
@Value("${remote.home}") |
||||
private URI home; |
||||
|
||||
@GetMapping("/test") |
||||
public Mono<ResponseEntity<?>> proxy(ProxyExchange<byte[]> proxy) throws Exception { |
||||
return proxy.uri(home.toString() + "/image/png").get(); |
||||
} |
||||
|
||||
} |
||||
---- |
||||
|
||||
Convenience methods on the `ProxyExchange` enable the handler method to discover and enhance the URI path of the incoming request. |
||||
For example, you might want to extract the trailing elements of a path to pass them downstream: |
||||
|
||||
[source,java] |
||||
---- |
||||
@GetMapping("/proxy/path/**") |
||||
public ResponseEntity<?> proxyPath(ProxyExchange<byte[]> proxy) throws Exception { |
||||
String path = proxy.path("/proxy/path/"); |
||||
return proxy.uri(home.toString() + "/foos/" + path).get(); |
||||
} |
||||
---- |
||||
|
||||
All the features of Spring MVC and Webflux are available to gateway handler methods. |
||||
As a result, you can inject request headers and query parameters, for instance, and you can constrain the incoming requests with declarations in the mapping annotation. |
||||
See the documentation for `@RequestMapping` in Spring MVC for more details of those features. |
||||
|
||||
You can add headers to the downstream response by using the `header()` methods on `ProxyExchange`. |
||||
|
||||
You can also manipulate response headers (and anything else you like in the response) by adding a mapper to the `get()` method (and other methods). |
||||
The mapper is a `Function` that takes the incoming `ResponseEntity` and converts it to an outgoing one. |
||||
|
||||
First-class support is provided for "`sensitive`" headers (by default, `cookie` and `authorization`), which are not passed downstream, and for "`proxy`" (`x-forwarded-*`) headers. |
||||
|
@ -0,0 +1,5 @@
@@ -0,0 +1,5 @@
|
||||
[[spring-cloud-gateway-server-mvc]] |
||||
= Spring Cloud Gateway Server MVC |
||||
:page-section-summary-toc: 1 |
||||
|
||||
// TODO: |
@ -0,0 +1,14 @@
@@ -0,0 +1,14 @@
|
||||
[[gateway-starter]] |
||||
= How to Include Spring Cloud Gateway Server MVC |
||||
:page-section-summary-toc: 1 |
||||
|
||||
To include Spring Cloud Gateway Server MVC in your project, use the starter with a group ID of `org.springframework.cloud` and an artifact ID of `spring-cloud-starter-gateway-mvc`. |
||||
See the https://projects.spring.io/spring-cloud/[Spring Cloud Project page] for details on setting up your build system with the current Spring Cloud Release Train. |
||||
|
||||
If you include the starter, but you do not want the gateway to be enabled, set `spring.cloud.gateway.enabled=false`. |
||||
|
||||
IMPORTANT: Spring Cloud Gateway Server MVC is built on https://spring.io/projects/spring-boot#learn[Spring Boot] and https://docs.spring.io/spring-framework/reference/web.html[Spring Web MVC]. |
||||
As a consequence, many of the asynchronous or reactive libraries may not apply when you use Spring Cloud Gateway Server MVC. |
||||
|
||||
IMPORTANT: Spring Cloud Gateway Server MVC works with traditional Servlet runtimes such as Tomcat and Jetty. |
||||
|
@ -0,0 +1,7 @@
@@ -0,0 +1,7 @@
|
||||
[[spring-cloud-gateway]] |
||||
= Spring Cloud Gateway Reactive Server |
||||
:page-section-summary-toc: 1 |
||||
|
||||
*{spring-cloud-version}* |
||||
|
||||
|
@ -0,0 +1,291 @@
@@ -0,0 +1,291 @@
|
||||
[[actuator-api]] |
||||
= Actuator API |
||||
|
||||
The `/gateway` actuator endpoint lets you monitor and interact with a Spring Cloud Gateway application. |
||||
To be remotely accessible, the endpoint has to be https://docs.spring.io/spring-boot/docs/current/reference/html/production-ready-endpoints.html#production-ready-endpoints-enabling-endpoints[enabled] and https://docs.spring.io/spring-boot/docs/current/reference/html/production-ready-endpoints.html#production-ready-endpoints-exposing-endpoints[exposed over HTTP or JMX] in the application properties. |
||||
The following listing shows how to do so: |
||||
|
||||
.application.properties |
||||
[source,properties] |
||||
---- |
||||
management.endpoint.gateway.enabled=true # default value |
||||
management.endpoints.web.exposure.include=gateway |
||||
---- |
||||
|
||||
[[verbose-actuator-format]] |
||||
== Verbose Actuator Format |
||||
|
||||
A new, more verbose format has been added to Spring Cloud Gateway. |
||||
It adds more detail to each route, letting you view the predicates and filters associated with each route along with any configuration that is available. |
||||
The following example configures `/actuator/gateway/routes`: |
||||
|
||||
[source,json] |
||||
---- |
||||
[ |
||||
{ |
||||
"predicate": "(Hosts: [**.addrequestheader.org] && Paths: [/headers], match trailing slash: true)", |
||||
"route_id": "add_request_header_test", |
||||
"filters": [ |
||||
"[[AddResponseHeader X-Response-Default-Foo = 'Default-Bar'], order = 1]", |
||||
"[[AddRequestHeader X-Request-Foo = 'Bar'], order = 1]", |
||||
"[[PrefixPath prefix = '/httpbin'], order = 2]" |
||||
], |
||||
"uri": "lb://testservice", |
||||
"order": 0 |
||||
} |
||||
] |
||||
---- |
||||
|
||||
This feature is enabled by default. To disable it, set the following property: |
||||
|
||||
.application.properties |
||||
[source,properties] |
||||
---- |
||||
spring.cloud.gateway.actuator.verbose.enabled=false |
||||
---- |
||||
|
||||
This will default to `true` in a future release. |
||||
|
||||
[[retrieving-route-filters]] |
||||
== Retrieving Route Filters |
||||
|
||||
This section details how to retrieve route filters, including: |
||||
|
||||
* xref:spring-cloud-gateway/actuator-api.adoc#gateway-global-filters[Global Filters] |
||||
* <<gateway-route-filters>> |
||||
|
||||
[[gateway-global-filters]] |
||||
=== Global Filters |
||||
|
||||
To retrieve the xref:spring-cloud-gateway/global-filters.adoc[global filters] applied to all routes, make a `GET` request to `/actuator/gateway/globalfilters`. The resulting response is similar to the following: |
||||
|
||||
---- |
||||
{ |
||||
"org.springframework.cloud.gateway.filter.ReactiveLoadBalancerClientFilter@77856cc5": 10100, |
||||
"org.springframework.cloud.gateway.filter.RouteToRequestUrlFilter@4f6fd101": 10000, |
||||
"org.springframework.cloud.gateway.filter.NettyWriteResponseFilter@32d22650": -1, |
||||
"org.springframework.cloud.gateway.filter.ForwardRoutingFilter@106459d9": 2147483647, |
||||
"org.springframework.cloud.gateway.filter.NettyRoutingFilter@1fbd5e0": 2147483647, |
||||
"org.springframework.cloud.gateway.filter.ForwardPathFilter@33a71d23": 0, |
||||
"org.springframework.cloud.gateway.filter.AdaptCachedBodyGlobalFilter@135064ea": 2147483637, |
||||
"org.springframework.cloud.gateway.filter.WebsocketRoutingFilter@23c05889": 2147483646 |
||||
} |
||||
---- |
||||
|
||||
The response contains the details of the global filters that are in place. |
||||
For each global filter, there is a string representation of the filter object (for example, `org.springframework.cloud.gateway.filter.ReactiveLoadBalancerClientFilter@77856cc5`) and the corresponding xref:spring-cloud-gateway/global-filters.adoc#gateway-combined-global-filter-and-gatewayfilter-ordering[order] in the filter chain. |
||||
|
||||
[[gateway-route-filters]] |
||||
=== Route Filters |
||||
To retrieve the xref:spring-cloud-gateway/gatewayfilter-factories.adoc[`GatewayFilter` factories] applied to routes, make a `GET` request to `/actuator/gateway/routefilters`. |
||||
The resulting response is similar to the following: |
||||
|
||||
---- |
||||
{ |
||||
"[AddRequestHeaderGatewayFilterFactory@570ed9c configClass = AbstractNameValueGatewayFilterFactory.NameValueConfig]": null, |
||||
"[SecureHeadersGatewayFilterFactory@fceab5d configClass = Object]": null, |
||||
"[SaveSessionGatewayFilterFactory@4449b273 configClass = Object]": null |
||||
} |
||||
---- |
||||
|
||||
The response contains the details of the `GatewayFilter` factories applied to any particular route. |
||||
For each factory there is a string representation of the corresponding object (for example, `[SecureHeadersGatewayFilterFactory@fceab5d configClass = Object]`). |
||||
Note that the `null` value is due to an incomplete implementation of the endpoint controller, because it tries to set the order of the object in the filter chain, which does not apply to a `GatewayFilter` factory object. |
||||
|
||||
[[refreshing-the-route-cache]] |
||||
== Refreshing the Route Cache |
||||
|
||||
To clear the routes cache, make a `POST` request to `/actuator/gateway/refresh`. |
||||
The request returns a 200 without a response body. |
||||
|
||||
To clear the routes with specific metadata values, add the Query parameter `metadata` specifying the `key:value` pairs that the routes to be cleared should match. |
||||
If an error is produced during the asynchronous refresh, the refresh will not modify the existing routes. |
||||
|
||||
Sending `POST` request to `/actuator/gateway/refresh?metadata=group:group-1` will only refresh the routes whose `group` metadata is `group-1`: `first_route` and `third_route`. |
||||
[source,json] |
||||
---- |
||||
[{ |
||||
"route_id": "first_route", |
||||
"route_object": { |
||||
"predicate": "...", |
||||
}, |
||||
"metadata": { "group": "group-1" } |
||||
}, |
||||
{ |
||||
"route_id": "second_route", |
||||
"route_object": { |
||||
"predicate": "...", |
||||
}, |
||||
"metadata": { "group": "group-2" } |
||||
}, |
||||
{ |
||||
"route_id": "third_route", |
||||
"route_object": { |
||||
"predicate": "...", |
||||
}, |
||||
"metadata": { "group": "group-1" } |
||||
}] |
||||
---- |
||||
|
||||
[[retrieving-the-routes-defined-in-the-gateway]] |
||||
== Retrieving the Routes Defined in the Gateway |
||||
|
||||
To retrieve the routes defined in the gateway, make a `GET` request to `/actuator/gateway/routes`. |
||||
The resulting response is similar to the following: |
||||
|
||||
---- |
||||
[{ |
||||
"route_id": "first_route", |
||||
"route_object": { |
||||
"predicate": "org.springframework.cloud.gateway.handler.predicate.PathRoutePredicateFactory$$Lambda$432/1736826640@1e9d7e7d", |
||||
"filters": [ |
||||
"OrderedGatewayFilter{delegate=org.springframework.cloud.gateway.filter.factory.PreserveHostHeaderGatewayFilterFactory$$Lambda$436/674480275@6631ef72, order=0}" |
||||
] |
||||
}, |
||||
"order": 0 |
||||
}, |
||||
{ |
||||
"route_id": "second_route", |
||||
"route_object": { |
||||
"predicate": "org.springframework.cloud.gateway.handler.predicate.PathRoutePredicateFactory$$Lambda$432/1736826640@cd8d298", |
||||
"filters": [] |
||||
}, |
||||
"order": 0 |
||||
}] |
||||
---- |
||||
|
||||
The response contains the details of all the routes defined in the gateway. |
||||
The following table describes the structure of each element (each is a route) of the response: |
||||
|
||||
[cols="3,2,4"] |
||||
|=== |
||||
| Path | Type | Description |
||||
|
||||
|`route_id` |
||||
| String |
||||
| The route ID. |
||||
|
||||
|`route_object.predicate` |
||||
| Object |
||||
| The route predicate. |
||||
|
||||
|`route_object.filters` |
||||
| Array |
||||
| The xref:spring-cloud-gateway/gatewayfilter-factories.adoc[`GatewayFilter` factories] applied to the route. |
||||
|
||||
|`order` |
||||
| Number |
||||
| The route order. |
||||
|
||||
|=== |
||||
|
||||
[[gateway-retrieving-information-about-a-particular-route]] |
||||
== Retrieving Information about a Particular Route |
||||
|
||||
To retrieve information about a single route, make a `GET` request to `/actuator/gateway/routes/\{id}` (for example, `/actuator/gateway/routes/first_route`). |
||||
The resulting response is similar to the following: |
||||
|
||||
---- |
||||
{ |
||||
"id": "first_route", |
||||
"predicates": [{ |
||||
"name": "Path", |
||||
"args": {"_genkey_0":"/first"} |
||||
}], |
||||
"filters": [], |
||||
"uri": "https://www.uri-destination.org", |
||||
"order": 0 |
||||
} |
||||
---- |
||||
|
||||
The following table describes the structure of the response: |
||||
|
||||
[cols="3,2,4"] |
||||
|=== |
||||
| Path | Type | Description |
||||
|
||||
|`id` |
||||
| String |
||||
| The route ID. |
||||
|
||||
|`predicates` |
||||
| Array |
||||
| The collection of route predicates. Each item defines the name and the arguments of a given predicate. |
||||
|
||||
|`filters` |
||||
| Array |
||||
| The collection of filters applied to the route. |
||||
|
||||
|`uri` |
||||
| String |
||||
| The destination URI of the route. |
||||
|
||||
|`order` |
||||
| Number |
||||
| The route order. |
||||
|
||||
|=== |
||||
|
||||
[[creating-and-deleting-a-particular-route-definition]] |
||||
== Creating and Deleting a Particular Route Definition |
||||
|
||||
To create a route definition, make a `POST` request to `/gateway/routes/\{id_route_to_create}` with a JSON body that specifies the fields of the route (see xref:spring-cloud-gateway/actuator-api.adoc#gateway-retrieving-information-about-a-particular-route[Retrieving Information about a Particular Route]). |
||||
|
||||
To delete a route definition, make a `DELETE` request to `/gateway/routes/\{id_route_to_delete}`. |
||||
|
||||
[[creating-multiple-route-definitions]] |
||||
== Creating multiple Route Definitions |
||||
|
||||
To create multiple route definitions in a single request, make a `POST` request to `/gateway/routes` with a JSON body that specifies the fields of the route, including the route id (see xref:spring-cloud-gateway/actuator-api.adoc#gateway-retrieving-information-about-a-particular-route[Retrieving Information about a Particular Route]). |
||||
|
||||
The route definitions will be discarded if any route raises an error during the creation of the routes. |
||||
|
||||
[[recap:-the-list-of-all-endpoints]] |
||||
== Recap: The List of All endpoints |
||||
|
||||
The following table below summarizes the Spring Cloud Gateway actuator endpoints (note that each endpoint has `/actuator/gateway` as the base-path): |
||||
|
||||
[cols="2,2,5"] |
||||
|=== |
||||
| ID | HTTP Method | Description |
||||
|
||||
|`globalfilters` |
||||
|GET |
||||
| Displays the list of global filters applied to the routes. |
||||
|
||||
|`routefilters` |
||||
|GET |
||||
| Displays the list of `GatewayFilter` factories applied to a particular route. |
||||
|
||||
|`refresh` |
||||
|POST |
||||
| Clears the routes cache. |
||||
|
||||
|`routes` |
||||
|GET |
||||
| Displays the list of routes defined in the gateway. |
||||
|
||||
|`routes/\{id}` |
||||
|GET |
||||
| Displays information about a particular route. |
||||
|
||||
|`routes/\{id}` |
||||
|POST |
||||
| Adds a new route to the gateway. |
||||
|
||||
|`routes/\{id}` |
||||
|DELETE |
||||
| Removes an existing route from the gateway. |
||||
|
||||
|=== |
||||
|
||||
[[sharing-routes-between-multiple-gateway-instances]] |
||||
== Sharing Routes between multiple Gateway instances |
||||
Spring Cloud Gateway offers two `RouteDefinitionRepository` implementations. The first one is the |
||||
`InMemoryRouteDefinitionRepository` which only lives within the memory of one Gateway instance. |
||||
This type of Repository is not suited to populate Routes across multiple Gateway instances. |
||||
|
||||
In order to share Routes across a cluster of Spring Cloud Gateway instances, `RedisRouteDefinitionRepository` can be used. |
||||
To enable this kind of repository, the following property has to set to true: `spring.cloud.gateway.redis-route-definition-repository.enabled` |
||||
Likewise to the RedisRateLimiter Filter Factory it requires the use of the spring-boot-starter-data-redis-reactive Spring Boot starter. |
||||
|
@ -0,0 +1,8 @@
@@ -0,0 +1,8 @@
|
||||
[[aot-and-native-image-support]] |
||||
= AOT and Native Image Support |
||||
:page-section-summary-toc: 1 |
||||
|
||||
Since `4.0.0`, Spring Cloud Gateway supports Spring AOT transformations and native images. |
||||
|
||||
TIP: If you're using load-balanced routes, you need to explicitly define your `LoadBalancerClient` service IDs. You can do so by using the `value` or `name` attributes of the `@LoadBalancerClient` annotation or as values of the `spring.cloud.loadbalancer.eager-load.clients` property. |
||||
|
@ -0,0 +1,5 @@
@@ -0,0 +1,5 @@
|
||||
[[configuration-properties]] |
||||
= Configuration properties |
||||
:page-section-summary-toc: 1 |
||||
|
||||
To see the list of all Spring Cloud Gateway related configuration properties, see link:appendix.html[the appendix]. |
@ -0,0 +1,45 @@
@@ -0,0 +1,45 @@
|
||||
[[configuration]] |
||||
= Configuration |
||||
|
||||
Configuration for Spring Cloud Gateway is driven by a collection of `RouteDefinitionLocator` instances. |
||||
The following listing shows the definition of the `RouteDefinitionLocator` interface: |
||||
|
||||
.RouteDefinitionLocator.java |
||||
[source,java] |
||||
---- |
||||
public interface RouteDefinitionLocator { |
||||
Flux<RouteDefinition> getRouteDefinitions(); |
||||
} |
||||
---- |
||||
|
||||
By default, a `PropertiesRouteDefinitionLocator` loads properties by using Spring Boot's `@ConfigurationProperties` mechanism. |
||||
|
||||
The earlier configuration examples all use a shortcut notation that uses positional arguments rather than named ones. |
||||
The following two examples are equivalent: |
||||
|
||||
.application.yml |
||||
[source,yaml] |
||||
---- |
||||
spring: |
||||
cloud: |
||||
gateway: |
||||
routes: |
||||
- id: setstatus_route |
||||
uri: https://example.org |
||||
filters: |
||||
- name: SetStatus |
||||
args: |
||||
status: 401 |
||||
- id: setstatusshortcut_route |
||||
uri: https://example.org |
||||
filters: |
||||
- SetStatus=401 |
||||
---- |
||||
|
||||
For some usages of the gateway, properties are adequate, but some production use cases benefit from loading configuration from an external source, such as a database. Future milestone versions will have `RouteDefinitionLocator` implementations based off of Spring Data Repositories, such as Redis, MongoDB, and Cassandra. |
||||
|
||||
[[routedefinition-metrics]] |
||||
== RouteDefinition Metrics |
||||
|
||||
To enable `RouteDefinition` metrics, add spring-boot-starter-actuator as a project dependency. Then, by default, the metrics will be available as long as the property `spring.cloud.gateway.metrics.enabled` is set to `true`. A gauge metric named `spring.cloud.gateway.routes.count` will be added, whose value is the number of `RouteDefinitions`. This metric will be available from `/actuator/metrics/spring.cloud.gateway.routes.count`. |
||||
|
@ -0,0 +1,50 @@
@@ -0,0 +1,50 @@
|
||||
[[configuring-route-predicate-factories-and-gateway-filter-factories]] |
||||
= Configuring Route Predicate Factories and Gateway Filter Factories |
||||
|
||||
There are two ways to configure predicates and filters: shortcuts and fully expanded arguments. Most examples below use the shortcut way. |
||||
|
||||
The name and argument names are listed as `code` in the first sentence or two of each section. The arguments are typically listed in the order that are needed for the shortcut configuration. |
||||
|
||||
[[shortcut-configuration]] |
||||
== Shortcut Configuration |
||||
|
||||
Shortcut configuration is recognized by the filter name, followed by an equals sign (`=`), followed by argument values separated by commas (`,`). |
||||
|
||||
.application.yml |
||||
[source,yaml] |
||||
---- |
||||
spring: |
||||
cloud: |
||||
gateway: |
||||
routes: |
||||
- id: after_route |
||||
uri: https://example.org |
||||
predicates: |
||||
- Cookie=mycookie,mycookievalue |
||||
---- |
||||
|
||||
The previous sample defines the `Cookie` Route Predicate Factory with two arguments, the cookie name, `mycookie` and the value to match `mycookievalue`. |
||||
|
||||
[[fully-expanded-arguments]] |
||||
== Fully Expanded Arguments |
||||
|
||||
Fully expanded arguments appear more like standard yaml configuration with name/value pairs. Typically, there will be a `name` key and an `args` key. The `args` key is a map of key value pairs to configure the predicate or filter. |
||||
|
||||
.application.yml |
||||
[source,yaml] |
||||
---- |
||||
spring: |
||||
cloud: |
||||
gateway: |
||||
routes: |
||||
- id: after_route |
||||
uri: https://example.org |
||||
predicates: |
||||
- name: Cookie |
||||
args: |
||||
name: mycookie |
||||
regexp: mycookievalue |
||||
---- |
||||
|
||||
This is the full configuration of the shortcut configuration of the `Cookie` predicate shown above. |
||||
|
@ -0,0 +1,61 @@
@@ -0,0 +1,61 @@
|
||||
[[cors-configuration]] |
||||
= CORS Configuration |
||||
:cors-configuration-docs-uri: https://docs.spring.io/spring/docs/5.0.x/javadoc-api/org/springframework/web/cors/CorsConfiguration.html |
||||
|
||||
You can configure the gateway to control CORS behavior globally or per route. |
||||
Both offer the same possibilities. |
||||
|
||||
[[global-cors-configuration]] |
||||
== Global CORS Configuration |
||||
|
||||
The "`global`" CORS configuration is a map of URL patterns to {cors-configuration-docs-uri}[Spring Framework `CorsConfiguration`]. |
||||
The following example configures CORS: |
||||
|
||||
.application.yml |
||||
[source,yaml] |
||||
---- |
||||
spring: |
||||
cloud: |
||||
gateway: |
||||
globalcors: |
||||
cors-configurations: |
||||
'[/**]': |
||||
allowedOrigins: "https://docs.spring.io" |
||||
allowedMethods: |
||||
- GET |
||||
---- |
||||
|
||||
In the preceding example, CORS requests are allowed from requests that originate from `docs.spring.io` for all GET requested paths. |
||||
|
||||
To provide the same CORS configuration to requests that are not handled by some gateway route predicate, set the `spring.cloud.gateway.globalcors.add-to-simple-url-handler-mapping` property to `true`. |
||||
This is useful when you try to support CORS preflight requests and your route predicate does not evaluate to `true` because the HTTP method is `options`. |
||||
|
||||
[[route-cors-configuration]] |
||||
== Route CORS Configuration |
||||
|
||||
The "`route`" configuration allows applying CORS directly to a route as metadata with key `cors`. |
||||
Like in the case of global configuration, the properties belong to {cors-configuration-docs-uri}[Spring Framework `CorsConfiguration`]. |
||||
|
||||
NOTE: If no `Path` predicate is present in the route '/**' will be applied. |
||||
|
||||
.application.yml |
||||
[source,yaml] |
||||
---- |
||||
spring: |
||||
cloud: |
||||
gateway: |
||||
routes: |
||||
- id: cors_route |
||||
uri: https://example.org |
||||
predicates: |
||||
- Path=/service/** |
||||
metadata: |
||||
cors |
||||
allowedOrigins: '*' |
||||
allowedMethods: |
||||
- GET |
||||
- POST |
||||
allowedHeaders: '*' |
||||
maxAge: 30 |
||||
---- |
||||
|
@ -0,0 +1,156 @@
@@ -0,0 +1,156 @@
|
||||
[[developer-guide]] |
||||
= Developer Guide |
||||
|
||||
These are basic guides to writing some custom components of the gateway. |
||||
|
||||
[[writing-custom-route-predicate-factories]] |
||||
== Writing Custom Route Predicate Factories |
||||
|
||||
|
||||
In order to write a Route Predicate you will need to implement `RoutePredicateFactory` as a bean. There is an abstract class called `AbstractRoutePredicateFactory` which you can extend. |
||||
|
||||
.MyRoutePredicateFactory.java |
||||
[source,java] |
||||
---- |
||||
@Component |
||||
public class MyRoutePredicateFactory extends AbstractRoutePredicateFactory<MyRoutePredicateFactory.Config> { |
||||
|
||||
public MyRoutePredicateFactory() { |
||||
super(Config.class); |
||||
} |
||||
|
||||
@Override |
||||
public Predicate<ServerWebExchange> apply(Config config) { |
||||
// grab configuration from Config object |
||||
return exchange -> { |
||||
//grab the request |
||||
ServerHttpRequest request = exchange.getRequest(); |
||||
//take information from the request to see if it |
||||
//matches configuration. |
||||
return matches(config, request); |
||||
}; |
||||
} |
||||
|
||||
public static class Config { |
||||
//Put the configuration properties for your filter here |
||||
} |
||||
|
||||
} |
||||
---- |
||||
[[writing-custom-gatewayfilter-factories]] |
||||
== Writing Custom GatewayFilter Factories |
||||
|
||||
To write a `GatewayFilter`, you must implement `GatewayFilterFactory` as a bean. |
||||
You can extend an abstract class called `AbstractGatewayFilterFactory`. |
||||
The following examples show how to do so: |
||||
|
||||
.PreGatewayFilterFactory.java |
||||
==== |
||||
[source,java] |
||||
---- |
||||
@Component |
||||
public class PreGatewayFilterFactory extends AbstractGatewayFilterFactory<PreGatewayFilterFactory.Config> { |
||||
|
||||
public PreGatewayFilterFactory() { |
||||
super(Config.class); |
||||
} |
||||
|
||||
@Override |
||||
public GatewayFilter apply(Config config) { |
||||
// grab configuration from Config object |
||||
return (exchange, chain) -> { |
||||
//If you want to build a "pre" filter you need to manipulate the |
||||
//request before calling chain.filter |
||||
ServerHttpRequest.Builder builder = exchange.getRequest().mutate(); |
||||
//use builder to manipulate the request |
||||
return chain.filter(exchange.mutate().request(builder.build()).build()); |
||||
}; |
||||
} |
||||
|
||||
public static class Config { |
||||
//Put the configuration properties for your filter here |
||||
} |
||||
|
||||
} |
||||
---- |
||||
|
||||
.PostGatewayFilterFactory.java |
||||
[source,java] |
||||
---- |
||||
@Component |
||||
public class PostGatewayFilterFactory extends AbstractGatewayFilterFactory<PostGatewayFilterFactory.Config> { |
||||
|
||||
public PostGatewayFilterFactory() { |
||||
super(Config.class); |
||||
} |
||||
|
||||
@Override |
||||
public GatewayFilter apply(Config config) { |
||||
// grab configuration from Config object |
||||
return (exchange, chain) -> { |
||||
return chain.filter(exchange).then(Mono.fromRunnable(() -> { |
||||
ServerHttpResponse response = exchange.getResponse(); |
||||
//Manipulate the response in some way |
||||
})); |
||||
}; |
||||
} |
||||
|
||||
public static class Config { |
||||
//Put the configuration properties for your filter here |
||||
} |
||||
|
||||
} |
||||
---- |
||||
==== |
||||
|
||||
[[naming-custom-filters-and-references-in-configuration]] |
||||
=== Naming Custom Filters And References In Configuration |
||||
|
||||
Custom filters class names should end in `GatewayFilterFactory`. |
||||
|
||||
For example, to reference a filter named `Something` in configuration files, the filter |
||||
must be in a class named `SomethingGatewayFilterFactory`. |
||||
|
||||
WARNING: It is possible to create a gateway filter named without the |
||||
`GatewayFilterFactory` suffix, such as `class AnotherThing`. This filter could be |
||||
referenced as `AnotherThing` in configuration files. This is **not** a supported naming |
||||
convention and this syntax may be removed in future releases. Please update the filter |
||||
name to be compliant. |
||||
|
||||
[[writing-custom-global-filters]] |
||||
== Writing Custom Global Filters |
||||
|
||||
To write a custom global filter, you must implement `GlobalFilter` interface as a bean. |
||||
This applies the filter to all requests. |
||||
|
||||
The following examples show how to set up global pre- and post-filters, respectively: |
||||
|
||||
[source,java] |
||||
---- |
||||
@Bean |
||||
public GlobalFilter customGlobalFilter() { |
||||
return (exchange, chain) -> exchange.getPrincipal() |
||||
.map(Principal::getName) |
||||
.defaultIfEmpty("Default User") |
||||
.map(userName -> { |
||||
//adds header to proxied request |
||||
exchange.getRequest().mutate().header("CUSTOM-REQUEST-HEADER", userName).build(); |
||||
return exchange; |
||||
}) |
||||
.flatMap(chain::filter); |
||||
} |
||||
|
||||
@Bean |
||||
public GlobalFilter customGlobalPostFilter() { |
||||
return (exchange, chain) -> chain.filter(exchange) |
||||
.then(Mono.just(exchange)) |
||||
.map(serverWebExchange -> { |
||||
//adds header to response |
||||
serverWebExchange.getResponse().getHeaders().set("CUSTOM-RESPONSE-HEADER", |
||||
HttpStatus.OK.equals(serverWebExchange.getResponse().getStatusCode()) ? "It worked": "It did not work"); |
||||
return serverWebExchange; |
||||
}) |
||||
.then(); |
||||
} |
||||
---- |
||||
|
@ -0,0 +1,41 @@
@@ -0,0 +1,41 @@
|
||||
[[fluent-java-routes-api]] |
||||
= Fluent Java Routes API |
||||
|
||||
To allow for simple configuration in Java, the `RouteLocatorBuilder` bean includes a fluent API. |
||||
The following listing shows how it works: |
||||
|
||||
.GatewaySampleApplication.java |
||||
[source,java] |
||||
---- |
||||
// static imports from GatewayFilters and RoutePredicates |
||||
@Bean |
||||
public RouteLocator customRouteLocator(RouteLocatorBuilder builder, ThrottleGatewayFilterFactory throttle) { |
||||
return builder.routes() |
||||
.route(r -> r.host("**.abc.org").and().path("/image/png") |
||||
.filters(f -> |
||||
f.addResponseHeader("X-TestHeader", "foobar")) |
||||
.uri("http://httpbin.org:80") |
||||
) |
||||
.route(r -> r.path("/image/webp") |
||||
.filters(f -> |
||||
f.addResponseHeader("X-AnotherHeader", "baz")) |
||||
.uri("http://httpbin.org:80") |
||||
.metadata("key", "value") |
||||
) |
||||
.route(r -> r.order(-1) |
||||
.host("**.throttle.org").and().path("/get") |
||||
.filters(f -> f.filter(throttle.apply(1, |
||||
1, |
||||
10, |
||||
TimeUnit.SECONDS))) |
||||
.uri("http://httpbin.org:80") |
||||
.metadata("key", "value") |
||||
) |
||||
.build(); |
||||
} |
||||
---- |
||||
|
||||
This style also allows for more custom predicate assertions. |
||||
The predicates defined by `RouteDefinitionLocator` beans are combined using logical `and`. |
||||
By using the fluent Java API, you can use the `and()`, `or()`, and `negate()` operators on the `Predicate` class. |
||||
|
@ -0,0 +1,10 @@
@@ -0,0 +1,10 @@
|
||||
[[gatewayfilter-factories]] |
||||
= `GatewayFilter` Factories |
||||
:page-section-summary-toc: 1 |
||||
|
||||
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 of how to use any of the following filters, take a look at the https://github.com/spring-cloud/spring-cloud-gateway/tree/master/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/filter/factory[unit tests]. |
||||
|
@ -0,0 +1,168 @@
@@ -0,0 +1,168 @@
|
||||
[[spring-cloud-circuitbreaker-filter-factory]] |
||||
= The `CircuitBreaker` `GatewayFilter` Factory |
||||
|
||||
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 `GatewayFilter`: |
||||
|
||||
.application.yml |
||||
[source,yaml] |
||||
---- |
||||
spring: |
||||
cloud: |
||||
gateway: |
||||
routes: |
||||
- id: circuitbreaker_route |
||||
uri: https://example.org |
||||
filters: |
||||
- CircuitBreaker=myCircuitBreaker |
||||
---- |
||||
|
||||
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: lb://backing-service:8088 |
||||
predicates: |
||||
- Path=/consumingServiceEndpoint |
||||
filters: |
||||
- name: CircuitBreaker |
||||
args: |
||||
name: myCircuitBreaker |
||||
fallbackUri: forward:/inCaseOfFailureUseThis |
||||
- RewritePath=/consumingServiceEndpoint, /backingServiceEndpoint |
||||
---- |
||||
|
||||
The following listing does the same thing in Java: |
||||
|
||||
.Application.java |
||||
[source,java] |
||||
---- |
||||
@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(); |
||||
} |
||||
---- |
||||
|
||||
This example forwards to the `/inCaseofFailureUseThis` URI when the circuit breaker fallback is called. |
||||
Note that this example also demonstrates the (optional) Spring Cloud LoadBalancer load-balancing (defined by the `lb` prefix on the destination URI). |
||||
|
||||
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`. |
||||
|
||||
.application.yml |
||||
[source,yaml] |
||||
---- |
||||
spring: |
||||
cloud: |
||||
gateway: |
||||
routes: |
||||
- id: circuitbreaker_route |
||||
uri: lb://backing-service:8088 |
||||
predicates: |
||||
- Path=/consumingServiceEndpoint/{*segments} |
||||
filters: |
||||
- name: CircuitBreaker |
||||
args: |
||||
name: myCircuitBreaker |
||||
fallbackUri: forward:/inCaseOfFailureUseThis/{segments} |
||||
---- |
||||
|
||||
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: |
||||
|
||||
.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 |
||||
---- |
||||
|
||||
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 `ServerWebExchange` as the `ServerWebExchangeUtils.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/gatewayfilter-factories/fallback-headers.adoc[FallbackHeaders GatewayFilter Factory 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" |
||||
---- |
||||
|
||||
.Application.java |
||||
[source,java] |
||||
---- |
||||
@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").addStatusCode("INTERNAL_SERVER_ERROR")) |
||||
.rewritePath("/consumingServiceEndpoint", "/backingServiceEndpoint")).uri("lb://backing-service:8088") |
||||
.build(); |
||||
} |
||||
---- |
||||
|
@ -0,0 +1,19 @@
@@ -0,0 +1,19 @@
|
||||
[[default-filters]] |
||||
= Default Filters |
||||
:page-section-summary-toc: 1 |
||||
|
||||
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. |
||||
The following listing defines a set of default filters: |
||||
|
||||
.application.yml |
||||
[source,yaml] |
||||
---- |
||||
spring: |
||||
cloud: |
||||
gateway: |
||||
default-filters: |
||||
- AddResponseHeader=X-Response-Default-Red, Default-Blue |
||||
- PrefixPath=/httpbin |
||||
---- |
||||
|
@ -0,0 +1,43 @@
@@ -0,0 +1,43 @@
|
||||
[[fallback-headers]] |
||||
= The `FallbackHeaders` `GatewayFilter` Factory |
||||
|
||||
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 |
||||
---- |
||||
|
||||
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/gatewayfilter-factories/circuitbreaker-filter-factory.adoc[Spring Cloud CircuitBreaker Factory section]. |
||||
|
@ -0,0 +1,55 @@
@@ -0,0 +1,55 @@
|
||||
[[local-cache-response-filter]] |
||||
= The `LocalResponseCache` `GatewayFilter` Factory |
||||
|
||||
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 `GatewayFilter`: |
||||
|
||||
[source,java] |
||||
---- |
||||
@Bean |
||||
public RouteLocator routes(RouteLocatorBuilder builder) { |
||||
return builder.routes() |
||||
.route("rewrite_response_upper", r -> r.host("*.rewriteresponseupper.org") |
||||
.filters(f -> f.prefixPath("/httpbin") |
||||
.localResponseCache(Duration.ofMinutes(30), "500MB") |
||||
).uri(uri)) |
||||
.build(); |
||||
} |
||||
---- |
||||
|
||||
or this |
||||
|
||||
.application.yaml |
||||
[source,yaml] |
||||
---- |
||||
spring: |
||||
cloud: |
||||
gateway: |
||||
routes: |
||||
- id: resource |
||||
uri: http://localhost:9000 |
||||
predicates: |
||||
- Path=/resource |
||||
filters: |
||||
- LocalResponseCache=30m,500MB |
||||
---- |
||||
|
||||
NOTE: This filter also automatically calculates the `max-age` value in the HTTP `Cache-Control` header. |
||||
Only if `max-age` is present on the original response is the value rewritten with the number of seconds set in the `timeToLive` configuration parameter. |
||||
In consecutive calls, this value is recalculated with the number of seconds left until the response expires. |
||||
|
||||
NOTE: To enable this feature, add `com.github.ben-manes.caffeine:caffeine` and `spring-boot-starter-cache` as project dependencies. |
||||
|
||||
WARNING: If your project creates custom `CacheManager` beans, it will either need to be marked with `@Primary` or injected using `@Qualifier`. |
||||
|
||||
|
@ -0,0 +1,42 @@
@@ -0,0 +1,42 @@
|
||||
[[removejsonattributesresponsebody-gatewayfilter-factory]] |
||||
= `RemoveJsonAttributesResponseBody` `GatewayFilter` Factory |
||||
|
||||
The `RemoveJsonAttributesResponseBody` `GatewayFilter` factory 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` `GatewayFilter`: |
||||
|
||||
.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` `GatewayFilter` that uses the optional last parameter: |
||||
|
||||
.application.yml |
||||
[source,yaml] |
||||
---- |
||||
spring: |
||||
cloud: |
||||
gateway: |
||||
routes: |
||||
- id: removejsonattributes_recursively_route |
||||
uri: https://example.org |
||||
predicates: |
||||
- Path=/red/{segment} |
||||
filters: |
||||
- RemoveJsonAttributesResponseBody=id,color,true |
||||
---- |
||||
|
||||
This removes attributes "id" and "color" from the JSON content body at any level. |
||||
|
@ -0,0 +1,40 @@
@@ -0,0 +1,40 @@
|
||||
[[the-addrequestheader-gatewayfilter-factory]] |
||||
= The `AddRequestHeader` `GatewayFilter` Factory |
||||
|
||||
The `AddRequestHeader` `GatewayFilter` factory takes a `name` and `value` parameter. |
||||
The following example configures an `AddRequestHeader` `GatewayFilter`: |
||||
|
||||
.application.yml |
||||
[source,yaml] |
||||
---- |
||||
spring: |
||||
cloud: |
||||
gateway: |
||||
routes: |
||||
- id: add_request_header_route |
||||
uri: https://example.org |
||||
filters: |
||||
- 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` `GatewayFilter` that uses a variable: |
||||
|
||||
.application.yml |
||||
[source,yaml] |
||||
---- |
||||
spring: |
||||
cloud: |
||||
gateway: |
||||
routes: |
||||
- id: add_request_header_route |
||||
uri: https://example.org |
||||
predicates: |
||||
- Path=/red/{segment} |
||||
filters: |
||||
- AddRequestHeader=X-Request-Red, Blue-{segment} |
||||
---- |
||||
|
@ -0,0 +1,44 @@
@@ -0,0 +1,44 @@
|
||||
[[the-addrequestheadersifnotpresent-gatewayfilter-factory]] |
||||
= The `AddRequestHeadersIfNotPresent` `GatewayFilter` Factory |
||||
|
||||
The `AddRequestHeadersIfNotPresent` `GatewayFilter` factory takes a collection of `name` and `value` pairs separated by colon. |
||||
The following example configures an `AddRequestHeadersIfNotPresent` `GatewayFilter`: |
||||
|
||||
.application.yml |
||||
[source,yaml] |
||||
---- |
||||
spring: |
||||
cloud: |
||||
gateway: |
||||
routes: |
||||
- id: add_request_headers_route |
||||
uri: https://example.org |
||||
filters: |
||||
- 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` `GatewayFilter` that uses a variable: |
||||
|
||||
.application.yml |
||||
[source,yaml] |
||||
---- |
||||
spring: |
||||
cloud: |
||||
gateway: |
||||
routes: |
||||
- id: add_request_header_route |
||||
uri: https://example.org |
||||
predicates: |
||||
- Path=/red/{segment} |
||||
filters: |
||||
- AddRequestHeadersIfNotPresent=X-Request-Red:Blue-{segment} |
||||
---- |
||||
|
@ -0,0 +1,40 @@
@@ -0,0 +1,40 @@
|
||||
[[the-addrequestparameter-gatewayfilter-factory]] |
||||
= The `AddRequestParameter` `GatewayFilter` Factory |
||||
|
||||
The `AddRequestParameter` `GatewayFilter` Factory takes a `name` and `value` parameter. |
||||
The following example configures an `AddRequestParameter` `GatewayFilter`: |
||||
|
||||
.application.yml |
||||
[source,yaml] |
||||
---- |
||||
spring: |
||||
cloud: |
||||
gateway: |
||||
routes: |
||||
- id: add_request_parameter_route |
||||
uri: https://example.org |
||||
filters: |
||||
- AddRequestParameter=red, blue |
||||
---- |
||||
|
||||
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` `GatewayFilter` that uses a variable: |
||||
|
||||
.application.yml |
||||
[source,yaml] |
||||
---- |
||||
spring: |
||||
cloud: |
||||
gateway: |
||||
routes: |
||||
- id: add_request_parameter_route |
||||
uri: https://example.org |
||||
predicates: |
||||
- Host: {segment}.myhost.org |
||||
filters: |
||||
- AddRequestParameter=foo, bar-{segment} |
||||
---- |
||||
|
@ -0,0 +1,41 @@
@@ -0,0 +1,41 @@
|
||||
[[the-addresponseheader-gatewayfilter-factory]] |
||||
= The `AddResponseHeader` `GatewayFilter` Factory |
||||
|
||||
The `AddResponseHeader` `GatewayFilter` Factory takes a `name` and `value` parameter. |
||||
The following example configures an `AddResponseHeader` `GatewayFilter`: |
||||
|
||||
.application.yml |
||||
[source,yaml] |
||||
---- |
||||
spring: |
||||
cloud: |
||||
gateway: |
||||
routes: |
||||
- id: add_response_header_route |
||||
uri: https://example.org |
||||
filters: |
||||
- AddResponseHeader=X-Response-Red, Blue |
||||
---- |
||||
|
||||
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` `GatewayFilter` that uses a variable: |
||||
|
||||
.application.yml |
||||
[source,yaml] |
||||
---- |
||||
spring: |
||||
cloud: |
||||
gateway: |
||||
routes: |
||||
- id: add_response_header_route |
||||
uri: https://example.org |
||||
predicates: |
||||
- Host: {segment}.myhost.org |
||||
filters: |
||||
- AddResponseHeader=foo, bar-{segment} |
||||
---- |
||||
|
||||
|
@ -0,0 +1,42 @@
@@ -0,0 +1,42 @@
|
||||
[[the-cacherequestbody-gatewayfilter-factory]] |
||||
= The `CacheRequestBody` `GatewayFilter` Factory |
||||
|
||||
Some situations necessitate reading the request body. Since the request can be read only once, we need to cache the request body. |
||||
You can use the `CacheRequestBody` filter to cache the request body before sending it downstream and getting the body from `exchange` attribute. |
||||
|
||||
The following listing shows how to cache the request body `GatewayFilter`: |
||||
|
||||
[source,java] |
||||
---- |
||||
@Bean |
||||
public RouteLocator routes(RouteLocatorBuilder builder) { |
||||
return builder.routes() |
||||
.route("cache_request_body_route", r -> r.path("/downstream/**") |
||||
.filters(f -> f.prefixPath("/httpbin") |
||||
.cacheRequestBody(String.class).uri(uri)) |
||||
.build(); |
||||
} |
||||
---- |
||||
|
||||
|
||||
.application.yml |
||||
[source,yaml] |
||||
---- |
||||
spring: |
||||
cloud: |
||||
gateway: |
||||
routes: |
||||
- id: cache_request_body_route |
||||
uri: lb://downstream |
||||
predicates: |
||||
- Path=/downstream/** |
||||
filters: |
||||
- name: CacheRequestBody |
||||
args: |
||||
bodyClass: java.lang.String |
||||
---- |
||||
`CacheRequestBody` extracts the request body and converts it to a body class (such as `java.lang.String`, defined in the preceding example). |
||||
`CacheRequestBody` then places it in the attributes available from `ServerWebExchange.getAttributes()`, with a key defined in `ServerWebExchangeUtils.CACHED_REQUEST_BODY_ATTR`. |
||||
|
||||
NOTE: This filter works only with HTTP (including HTTPS) requests. |
||||
|
@ -0,0 +1,25 @@
@@ -0,0 +1,25 @@
|
||||
[[the-deduperesponseheader-gatewayfilter-factory]] |
||||
= The `DedupeResponseHeader` `GatewayFilter` Factory |
||||
|
||||
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` `GatewayFilter`: |
||||
|
||||
.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 |
||||
---- |
||||
|
||||
This removes duplicate values of `Access-Control-Allow-Credentials` and `Access-Control-Allow-Origin` response headers in cases when both the gateway CORS logic and the downstream logic add them. |
||||
|
||||
The `DedupeResponseHeader` filter also accepts an optional `strategy` parameter. |
||||
The accepted values are `RETAIN_FIRST` (default), `RETAIN_LAST`, and `RETAIN_UNIQUE`. |
||||
|
||||
|
@ -0,0 +1,80 @@
@@ -0,0 +1,80 @@
|
||||
[[the-jsontogrpc-gatewayfilter-factory]] |
||||
= The `JsonToGrpc` `GatewayFilter` Factory |
||||
|
||||
The JSONToGRPCFilter GatewayFilter Factory converts a JSON payload to a gRPC request. |
||||
|
||||
The filter takes the following arguments: |
||||
|
||||
* `protoDescriptor`: Proto descriptor file. |
||||
|
||||
This file can be generated using `protoc` and specifying the `--descriptor_set_out` flag: |
||||
|
||||
[source,bash] |
||||
---- |
||||
protoc --proto_path=src/main/resources/proto/ \ |
||||
--descriptor_set_out=src/main/resources/proto/hello.pb \ |
||||
src/main/resources/proto/hello.proto |
||||
---- |
||||
|
||||
* `protoFile`: Proto definition file. |
||||
|
||||
* `service`: Short name of the service that handles the request. |
||||
|
||||
* `method`: Method name in the service that handles the request. |
||||
|
||||
NOTE: `streaming` is not supported. |
||||
|
||||
|
||||
*application.yml.* |
||||
|
||||
[source,java] |
||||
---- |
||||
@Bean |
||||
public RouteLocator routes(RouteLocatorBuilder builder) { |
||||
return builder.routes() |
||||
.route("json-grpc", r -> r.path("/json/hello").filters(f -> { |
||||
String protoDescriptor = "file:src/main/proto/hello.pb"; |
||||
String protoFile = "file:src/main/proto/hello.proto"; |
||||
String service = "HelloService"; |
||||
String method = "hello"; |
||||
return f.jsonToGRPC(protoDescriptor, protoFile, service, method); |
||||
}).uri(uri)) |
||||
---- |
||||
|
||||
[source,yaml] |
||||
---- |
||||
spring: |
||||
cloud: |
||||
gateway: |
||||
routes: |
||||
- id: json-grpc |
||||
uri: https://localhost:6565/testhello |
||||
predicates: |
||||
- Path=/json/** |
||||
filters: |
||||
- name: JsonToGrpc |
||||
args: |
||||
protoDescriptor: file:proto/hello.pb |
||||
protoFile: file:proto/hello.proto |
||||
service: HelloService |
||||
method: hello |
||||
|
||||
---- |
||||
|
||||
When a request is made through the gateway to `/json/hello`, the request is transformed by using the definition provided in `hello.proto`, sent to `HelloService/hello`, and the response back is transformed to JSON. |
||||
|
||||
By default, it creates a `NettyChannel` by using the default `TrustManagerFactory`. However, you can customize this `TrustManager` by creating a bean of type `GrpcSslConfigurer`: |
||||
|
||||
[source,java] |
||||
---- |
||||
|
||||
@Configuration |
||||
public class GRPCLocalConfiguration { |
||||
@Bean |
||||
public GRPCSSLContext sslContext() { |
||||
TrustManager trustManager = trustAllCerts(); |
||||
return new GRPCSSLContext(trustManager); |
||||
} |
||||
} |
||||
---- |
||||
|
@ -0,0 +1,24 @@
@@ -0,0 +1,24 @@
|
||||
[[the-maprequestheader-gatewayfilter-factory]] |
||||
= The `MapRequestHeader` `GatewayFilter` Factory |
||||
|
||||
The `MapRequestHeader` `GatewayFilter` factory 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`: |
||||
|
||||
.application.yml |
||||
[source,yaml] |
||||
---- |
||||
spring: |
||||
cloud: |
||||
gateway: |
||||
routes: |
||||
- id: map_request_header_route |
||||
uri: https://example.org |
||||
filters: |
||||
- MapRequestHeader=Blue, X-Request-Red |
||||
---- |
||||
|
||||
This adds the `X-Request-Red:<values>` header to the downstream request with updated values from the incoming HTTP request's `Blue` header. |
||||
|
@ -0,0 +1,44 @@
@@ -0,0 +1,44 @@
|
||||
[[the-modifyrequestbody-gatewayfilter-factory]] |
||||
= The `ModifyRequestBody` `GatewayFilter` Factory |
||||
|
||||
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 `GatewayFilter`: |
||||
|
||||
[source,java] |
||||
---- |
||||
@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) -> 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; |
||||
} |
||||
} |
||||
---- |
||||
|
||||
NOTE: If the request has no body, the `RewriteFilter` is passed `null`. `Mono.empty()` should be returned to assign a missing body in the request. |
||||
|
||||
|
||||
|
@ -0,0 +1,24 @@
@@ -0,0 +1,24 @@
|
||||
[[the-modifyresponsebody-gatewayfilter-factory]] |
||||
= The `ModifyResponseBody` `GatewayFilter` Factory |
||||
|
||||
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 `GatewayFilter`: |
||||
|
||||
[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(); |
||||
} |
||||
---- |
||||
|
||||
NOTE: If the response has no body, the `RewriteFilter` is passed `null`. `Mono.empty()` should be returned to assign a missing body in the response. |
||||
|
@ -0,0 +1,23 @@
@@ -0,0 +1,23 @@
|
||||
[[the-prefixpath-gatewayfilter-factory]] |
||||
= The `PrefixPath` `GatewayFilter` Factory |
||||
:page-section-summary-toc: 1 |
||||
|
||||
The `PrefixPath` `GatewayFilter` factory takes a single `prefix` parameter. |
||||
The following example configures a `PrefixPath` `GatewayFilter`: |
||||
|
||||
.application.yml |
||||
[source,yaml] |
||||
---- |
||||
spring: |
||||
cloud: |
||||
gateway: |
||||
routes: |
||||
- id: prefixpath_route |
||||
uri: https://example.org |
||||
filters: |
||||
- PrefixPath=/mypath |
||||
---- |
||||
|
||||
This prefixes `/mypath` to the path of all matching requests. |
||||
So a request to `/hello` is sent to `/mypath/hello`. |
||||
|
@ -0,0 +1,21 @@
@@ -0,0 +1,21 @@
|
||||
[[the-preservehostheader-gatewayfilter-factory]] |
||||
= The `PreserveHostHeader` `GatewayFilter` Factory |
||||
:page-section-summary-toc: 1 |
||||
|
||||
The `PreserveHostHeader` `GatewayFilter` factory has no parameters. |
||||
This filter sets a request attribute that the routing filter 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` `GatewayFilter`: |
||||
|
||||
.application.yml |
||||
[source,yaml] |
||||
---- |
||||
spring: |
||||
cloud: |
||||
gateway: |
||||
routes: |
||||
- id: preserve_host_route |
||||
uri: https://example.org |
||||
filters: |
||||
- PreserveHostHeader |
||||
---- |
||||
|
@ -0,0 +1,26 @@
@@ -0,0 +1,26 @@
|
||||
[[the-redirectto-gatewayfilter-factory]] |
||||
= The `RedirectTo` `GatewayFilter` Factory |
||||
|
||||
The `RedirectTo` `GatewayFilter` factory 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` `GatewayFilter`: |
||||
|
||||
.application.yml |
||||
[source,yaml] |
||||
---- |
||||
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. |
||||
|
||||
|
@ -0,0 +1,23 @@
@@ -0,0 +1,23 @@
|
||||
[[the-removerequestheader-gatewayfilter-factory]] |
||||
= The `RemoveRequestHeader` GatewayFilter Factory |
||||
:page-section-summary-toc: 1 |
||||
|
||||
The `RemoveRequestHeader` `GatewayFilter` factory takes a `name` parameter. |
||||
It is the name of the header to be removed. |
||||
The following listing configures a `RemoveRequestHeader` `GatewayFilter`: |
||||
|
||||
.application.yml |
||||
[source,yaml] |
||||
---- |
||||
spring: |
||||
cloud: |
||||
gateway: |
||||
routes: |
||||
- id: removerequestheader_route |
||||
uri: https://example.org |
||||
filters: |
||||
- RemoveRequestHeader=X-Request-Foo |
||||
---- |
||||
|
||||
This removes the `X-Request-Foo` header before it is sent downstream. |
||||
|
@ -0,0 +1,24 @@
@@ -0,0 +1,24 @@
|
||||
[[the-removerequestparameter-gatewayfilter-factory]] |
||||
= The `RemoveRequestParameter` `GatewayFilter` Factory |
||||
:page-section-summary-toc: 1 |
||||
|
||||
The `RemoveRequestParameter` `GatewayFilter` factory takes a `name` parameter. |
||||
It is the name of the query parameter to be removed. |
||||
The following example configures a `RemoveRequestParameter` `GatewayFilter`: |
||||
|
||||
.application.yml |
||||
[source,yaml] |
||||
---- |
||||
spring: |
||||
cloud: |
||||
gateway: |
||||
routes: |
||||
- id: removerequestparameter_route |
||||
uri: https://example.org |
||||
filters: |
||||
- RemoveRequestParameter=red |
||||
---- |
||||
|
||||
This will remove the `red` parameter before it is sent downstream. |
||||
|
||||
|
@ -0,0 +1,26 @@
@@ -0,0 +1,26 @@
|
||||
[[the-removeresponseheader-gatewayfilter-factory]] |
||||
= The `RemoveResponseHeader` `GatewayFilter` Factory |
||||
|
||||
The `RemoveResponseHeader` `GatewayFilter` factory takes a `name` parameter. |
||||
It is the name of the header to be removed. |
||||
The following listing configures a `RemoveResponseHeader` `GatewayFilter`: |
||||
|
||||
.application.yml |
||||
[source,yaml] |
||||
---- |
||||
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 for which you may want to do so. |
||||
In addition, you can configure this filter once by using `spring.cloud.gateway.default-filters` and have it applied to all routes. |
||||
|
||||
|
@ -0,0 +1,23 @@
@@ -0,0 +1,23 @@
|
||||
[[the-requestheadersize-gatewayfilter-factory]] |
||||
= The `RequestHeaderSize` `GatewayFilter` Factory |
||||
:page-section-summary-toc: 1 |
||||
|
||||
The `RequestHeaderSize` `GatewayFilter` factory 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` `GatewayFilter`: |
||||
|
||||
.application.yml |
||||
[source,yaml] |
||||
---- |
||||
spring: |
||||
cloud: |
||||
gateway: |
||||
routes: |
||||
- id: requestheadersize_route |
||||
uri: https://example.org |
||||
filters: |
||||
- RequestHeaderSize=1000B |
||||
---- |
||||
|
||||
This will send a status 431 if size of any request header is greater than 1000 Bytes. |
||||
|
@ -0,0 +1,120 @@
@@ -0,0 +1,120 @@
|
||||
[[the-requestratelimiter-gatewayfilter-factory]] |
||||
= The `RequestRateLimiter` `GatewayFilter` Factory |
||||
|
||||
The `RequestRateLimiter` `GatewayFilter` factory 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/the-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} |
||||
---- |
||||
===== |
||||
|
||||
[[the-redis-ratelimiter]] |
||||
== The Redis `RateLimiter` |
||||
|
||||
The Redis implementation is based on work done at https://stripe.com/blog/rate-limiters[Stripe]. |
||||
It requires the use of the `spring-boot-starter-data-redis-reactive` Spring Boot starter. |
||||
|
||||
The algorithm used is the https://en.wikipedia.org/wiki/Token_bucket[Token Bucket Algorithm]. |
||||
|
||||
The `redis-rate-limiter.replenishRate` property defines how many requests per second to allow (without any dropped requests). |
||||
This is the rate at which the token bucket is filled. |
||||
|
||||
The `redis-rate-limiter.burstCapacity` property is the maximum number of requests a user is allowed in a single second (without any dropped requests). |
||||
This is the number of tokens the token bucket can hold. |
||||
Setting this value to zero blocks all requests. |
||||
|
||||
The `redis-rate-limiter.requestedTokens` property is how many tokens a request costs. |
||||
This is the number of tokens taken from the bucket for each request and defaults to `1`. |
||||
|
||||
A steady rate is accomplished by setting the same value in `replenishRate` and `burstCapacity`. |
||||
Temporary bursts can be allowed by setting `burstCapacity` higher than `replenishRate`. |
||||
In this case, the rate limiter needs to be allowed some time between bursts (according to `replenishRate`), as two consecutive bursts results in dropped requests (`HTTP 429 - Too Many Requests`). |
||||
The following listing configures a `redis-rate-limiter`: |
||||
|
||||
Rate limits below `1 request/s` are accomplished by setting `replenishRate` to the wanted number of requests, `requestedTokens` to the timespan in seconds, and `burstCapacity` to the product of `replenishRate` and `requestedTokens`. |
||||
For example, setting `replenishRate=1`, `requestedTokens=60`, and `burstCapacity=60` results in a limit of `1 request/min`. |
||||
.application.yml |
||||
[source,yaml] |
||||
---- |
||||
spring: |
||||
cloud: |
||||
gateway: |
||||
routes: |
||||
- id: requestratelimiter_route |
||||
uri: https://example.org |
||||
filters: |
||||
- name: RequestRateLimiter |
||||
args: |
||||
redis-rate-limiter.replenishRate: 10 |
||||
redis-rate-limiter.burstCapacity: 20 |
||||
redis-rate-limiter.requestedTokens: 1 |
||||
|
||||
---- |
||||
|
||||
The following example configures a `KeyResolver` in Java: |
||||
|
||||
.Config.java |
||||
[source,java] |
||||
---- |
||||
@Bean |
||||
KeyResolver userKeyResolver() { |
||||
return exchange -> Mono.just(exchange.getRequest().getQueryParams().getFirst("user")); |
||||
} |
||||
---- |
||||
|
||||
This defines a request rate limit of 10 per user. A burst of 20 is allowed, but, in the next second, only 10 requests are available. |
||||
The `KeyResolver` is a simple one that gets the `user` request parameter |
||||
NOTE: This is not recommended for production |
||||
|
||||
You can also define a rate limiter as a bean that implements the `RateLimiter` interface. |
||||
In configuration, you can reference the bean by name using SpEL. |
||||
`#{@myRateLimiter}` is a SpEL expression that references a bean with named `myRateLimiter`. |
||||
The following listing defines a rate limiter that uses the `KeyResolver` defined in the previous listing: |
||||
|
||||
.application.yml |
||||
[source,yaml] |
||||
---- |
||||
spring: |
||||
cloud: |
||||
gateway: |
||||
routes: |
||||
- id: requestratelimiter_route |
||||
uri: https://example.org |
||||
filters: |
||||
- name: RequestRateLimiter |
||||
args: |
||||
rate-limiter: "#{@myRateLimiter}" |
||||
key-resolver: "#{@userKeyResolver}" |
||||
|
||||
---- |
||||
|
@ -0,0 +1,35 @@
@@ -0,0 +1,35 @@
|
||||
[[the-requestsize-gatewayfilter-factory]] |
||||
= The `RequestSize` `GatewayFilter` Factory |
||||
|
||||
When the request size is greater than the permissible limit, the `RequestSize` `GatewayFilter` factory 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` `GatewayFilter`: |
||||
|
||||
.application.yml |
||||
[source,yaml] |
||||
---- |
||||
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 sets the response status as `413 Payload Too Large` with an additional header `errorMessage` when the request is rejected due to size. The following example shows such an `errorMessage`: |
||||
|
||||
[source] |
||||
---- |
||||
errorMessage : Request size is larger than permissible limit. Request size is 6.0 MB where permissible limit is 5.0 MB |
||||
---- |
||||
|
||||
NOTE: The default request size is set to five MB if not provided as a filter argument in the route definition. |
||||
|
@ -0,0 +1,86 @@
@@ -0,0 +1,86 @@
|
||||
[[the-retry-gatewayfilter-factory]] |
||||
= The `Retry` `GatewayFilter` Factory |
||||
|
||||
The `Retry` `GatewayFilter` factory 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 `GatewayFilter`: |
||||
|
||||
.application.yml |
||||
[source,yaml] |
||||
---- |
||||
spring: |
||||
cloud: |
||||
gateway: |
||||
routes: |
||||
- id: retry_test |
||||
uri: http://localhost:8080/flakey |
||||
predicates: |
||||
- Host=*.retry.com |
||||
filters: |
||||
- name: Retry |
||||
args: |
||||
retries: 3 |
||||
statuses: BAD_GATEWAY |
||||
methods: GET,POST |
||||
backoff: |
||||
firstBackoff: 10ms |
||||
maxBackoff: 50ms |
||||
factor: 2 |
||||
basedOnPreviousValue: false |
||||
---- |
||||
|
||||
NOTE: When using the retry filter with a `forward:` prefixed URL, the target endpoint should be written carefully so that, in case of an error, it does not do anything that could result in a response being sent to the client and committed. |
||||
For example, if the target endpoint is an annotated controller, the target controller method should not return `ResponseEntity` with an error status code. |
||||
Instead, it should throw an `Exception` or signal an error (for example, through a `Mono.error(ex)` return value), which the retry filter can be configured to handle by retrying. |
||||
|
||||
WARNING: When using the retry filter with any HTTP method with a body, the body will be cached and the gateway will become memory constrained. The body is cached in a request attribute defined by `ServerWebExchangeUtils.CACHED_REQUEST_BODY_ATTR`. The type of the object is `org.springframework.core.io.buffer.DataBuffer`. |
||||
|
||||
A simplified "shortcut" notation can be added with a single `status` and `method`. |
||||
|
||||
The following two examples are equivalent: |
||||
|
||||
.application.yml |
||||
[source,yaml] |
||||
---- |
||||
spring: |
||||
cloud: |
||||
gateway: |
||||
routes: |
||||
- id: retry_route |
||||
uri: https://example.org |
||||
filters: |
||||
- name: Retry |
||||
args: |
||||
retries: 3 |
||||
statuses: INTERNAL_SERVER_ERROR |
||||
methods: GET |
||||
backoff: |
||||
firstBackoff: 10ms |
||||
maxBackoff: 50ms |
||||
factor: 2 |
||||
basedOnPreviousValue: false |
||||
|
||||
- id: retryshortcut_route |
||||
uri: https://example.org |
||||
filters: |
||||
- Retry=3,INTERNAL_SERVER_ERROR,GET,10ms,50ms,2,false |
||||
---- |
||||
|
@ -0,0 +1,35 @@
@@ -0,0 +1,35 @@
|
||||
[[the-rewritelocationresponseheader-gatewayfilter-factory]] |
||||
= The `RewriteLocationResponseHeader` `GatewayFilter` Factory |
||||
|
||||
The `RewriteLocationResponseHeader` `GatewayFilter` factory 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` `GatewayFilter`: |
||||
|
||||
.application.yml |
||||
[source,yaml] |
||||
---- |
||||
spring: |
||||
cloud: |
||||
gateway: |
||||
routes: |
||||
- id: rewritelocationresponseheader_route |
||||
uri: http://example.org |
||||
filters: |
||||
- RewriteLocationResponseHeader=AS_IN_REQUEST, Location, , |
||||
---- |
||||
|
||||
For example, for a request of `POST https://api.example.com/some/object/name`, the `Location` response header value of `https://object-service.prod.example.net/v2/some/object/id` is rewritten as `https://api.example.com/some/object/id`. |
||||
|
||||
The `stripVersionMode` parameter has the following possible values: `NEVER_STRIP`, `AS_IN_REQUEST` (default), and `ALWAYS_STRIP`. |
||||
|
||||
* `NEVER_STRIP`: The version is not stripped, even if the original request path contains no version. |
||||
* `AS_IN_REQUEST`: The version is stripped only if the original request path contains no version. |
||||
* `ALWAYS_STRIP`: The version is always stripped, even if the original request path contains version. |
||||
|
||||
The `hostValue` parameter, if provided, is used to replace the `host:port` portion of the response `Location` header. |
||||
If it is not provided, the value of the `Host` request header is used. |
||||
|
||||
The `protocolsRegex` parameter must be a valid regex `String`, against which the protocol name is matched. |
||||
If it is not matched, the filter does nothing. |
||||
The default is `http|https|ftp|ftps`. |
||||
|
@ -0,0 +1,24 @@
@@ -0,0 +1,24 @@
|
||||
[[the-rewritepath-gatewayfilter-factory]] |
||||
= The `RewritePath` `GatewayFilter` Factory |
||||
|
||||
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. |
||||
The following listing configures a `RewritePath` `GatewayFilter`: |
||||
|
||||
.application.yml |
||||
[source,yaml] |
||||
---- |
||||
spring: |
||||
cloud: |
||||
gateway: |
||||
routes: |
||||
- id: rewritepath_route |
||||
uri: https://example.org |
||||
predicates: |
||||
- Path=/red/** |
||||
filters: |
||||
- RewritePath=/red/?(?<segment>.*), /$\{segment} |
||||
---- |
||||
|
||||
For a request path of `/red/blue`, this sets the path to `/blue` before making the downstream request. Note that the `$` should be replaced with `$\` because of the YAML specification. |
||||
|
@ -0,0 +1,24 @@
@@ -0,0 +1,24 @@
|
||||
[[the-rewriteresponseheader-gatewayfilter-factory]] |
||||
= The `RewriteResponseHeader` `GatewayFilter` Factory |
||||
:page-section-summary-toc: 1 |
||||
|
||||
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. |
||||
The following example configures a `RewriteResponseHeader` `GatewayFilter`: |
||||
|
||||
.application.yml |
||||
[source,yaml] |
||||
---- |
||||
spring: |
||||
cloud: |
||||
gateway: |
||||
routes: |
||||
- id: rewriteresponseheader_route |
||||
uri: https://example.org |
||||
filters: |
||||
- RewriteResponseHeader=X-Response-Red, , password=[^&]+, password=*** |
||||
---- |
||||
|
||||
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. |
||||
|
@ -0,0 +1,24 @@
@@ -0,0 +1,24 @@
|
||||
[[the-savesession-gatewayfilter-factory]] |
||||
= The `SaveSession` `GatewayFilter` Factory |
||||
|
||||
The `SaveSession` `GatewayFilter` factory 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` `GatewayFilter`: |
||||
|
||||
.application.yml |
||||
[source,yaml] |
||||
---- |
||||
spring: |
||||
cloud: |
||||
gateway: |
||||
routes: |
||||
- id: save_session |
||||
uri: https://example.org |
||||
predicates: |
||||
- Path=/foo/** |
||||
filters: |
||||
- SaveSession |
||||
---- |
||||
|
||||
If you integrate https://projects.spring.io/spring-security/[Spring Security] with Spring Session and want to ensure security details have been forwarded to the remote process, this is critical. |
||||
|
@ -0,0 +1,38 @@
@@ -0,0 +1,38 @@
|
||||
[[the-secureheaders-gatewayfilter-factory]] |
||||
= The `SecureHeaders` `GatewayFilter` Factory |
||||
|
||||
The `SecureHeaders` `GatewayFilter` factory adds a number of headers to the response, per the recommendation made in https://blog.appcanary.com/2017/http-security-headers.html[this blog post]. |
||||
|
||||
The following headers (shown with their default values) are added: |
||||
|
||||
* `X-Xss-Protection:1 (mode=block`) |
||||
* `Strict-Transport-Security (max-age=631138519`) |
||||
* `X-Frame-Options (DENY)` |
||||
* `X-Content-Type-Options (nosniff)` |
||||
* `Referrer-Policy (no-referrer)` |
||||
* `Content-Security-Policy (default-src 'self' https:; font-src 'self' https: data:; img-src 'self' https: data:; object-src 'none'; script-src https:; style-src 'self' https: 'unsafe-inline)'` |
||||
* `X-Download-Options (noopen)` |
||||
* `X-Permitted-Cross-Domain-Policies (none)` |
||||
|
||||
To change the default values, set the appropriate property in the `spring.cloud.gateway.filter.secure-headers` namespace. |
||||
The following properties are available: |
||||
|
||||
* `xss-protection-header` |
||||
* `strict-transport-security` |
||||
* `frame-options` |
||||
* `content-type-options` |
||||
* `referrer-policy` |
||||
* `content-security-policy` |
||||
* `download-options` |
||||
* `permitted-cross-domain-policies` |
||||
|
||||
To disable the default values set the `spring.cloud.gateway.filter.secure-headers.disable` property with comma-separated values. |
||||
The following example shows how to do so: |
||||
|
||||
[source] |
||||
---- |
||||
spring.cloud.gateway.filter.secure-headers.disable=x-frame-options,strict-transport-security |
||||
---- |
||||
|
||||
NOTE: The lowercase full name of the secure header needs to be used to disable it.. |
||||
|
@ -0,0 +1,26 @@
@@ -0,0 +1,26 @@
|
||||
[[the-setpath-gatewayfilter-factory]] |
||||
= The `SetPath` `GatewayFilter` Factory |
||||
|
||||
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. |
||||
The following example configures a `SetPath` `GatewayFilter`: |
||||
|
||||
.application.yml |
||||
[source,yaml] |
||||
---- |
||||
spring: |
||||
cloud: |
||||
gateway: |
||||
routes: |
||||
- id: setpath_route |
||||
uri: https://example.org |
||||
predicates: |
||||
- Path=/red/{segment} |
||||
filters: |
||||
- SetPath=/{segment} |
||||
---- |
||||
|
||||
For a request path of `/red/blue`, this sets the path to `/blue` before making the downstream request. |
||||
|
@ -0,0 +1,41 @@
@@ -0,0 +1,41 @@
|
||||
[[the-setrequestheader-gatewayfilter-factory]] |
||||
= The `SetRequestHeader` `GatewayFilter` Factory |
||||
|
||||
The `SetRequestHeader` `GatewayFilter` factory takes `name` and `value` parameters. |
||||
The following listing configures a `SetRequestHeader` `GatewayFilter`: |
||||
|
||||
.application.yml |
||||
[source,yaml] |
||||
---- |
||||
spring: |
||||
cloud: |
||||
gateway: |
||||
routes: |
||||
- id: setrequestheader_route |
||||
uri: https://example.org |
||||
filters: |
||||
- SetRequestHeader=X-Request-Red, Blue |
||||
---- |
||||
|
||||
This `GatewayFilter` 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` `GatewayFilter` 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=foo, bar-{segment} |
||||
---- |
||||
|
@ -0,0 +1,27 @@
@@ -0,0 +1,27 @@
|
||||
[[the-setrequesthostheader-gatewayfilter-factory]] |
||||
= The `SetRequestHostHeader` `GatewayFilter` Factory |
||||
|
||||
There are certain situation when the host header may need to be overridden. In this situation, the `SetRequestHostHeader` `GatewayFilter` factory can replace the existing host header with a specified value. |
||||
The filter takes a `host` parameter. |
||||
The following listing configures a `SetRequestHostHeader` `GatewayFilter`: |
||||
|
||||
.application.yml |
||||
[source,yaml] |
||||
---- |
||||
spring: |
||||
cloud: |
||||
gateway: |
||||
routes: |
||||
- id: set_request_host_header_route |
||||
uri: http://localhost:8080/headers |
||||
predicates: |
||||
- Path=/headers |
||||
filters: |
||||
- name: SetRequestHostHeader |
||||
args: |
||||
host: example.org |
||||
---- |
||||
|
||||
The `SetRequestHostHeader` `GatewayFilter` factory replaces the value of the host header with `example.org`. |
||||
|
||||
|
@ -0,0 +1,41 @@
@@ -0,0 +1,41 @@
|
||||
[[the-setresponseheader-gatewayfilter-factory]] |
||||
= The `SetResponseHeader` `GatewayFilter` Factory |
||||
|
||||
The `SetResponseHeader` `GatewayFilter` factory takes `name` and `value` parameters. |
||||
The following listing configures a `SetResponseHeader` `GatewayFilter`: |
||||
|
||||
.application.yml |
||||
[source,yaml] |
||||
---- |
||||
spring: |
||||
cloud: |
||||
gateway: |
||||
routes: |
||||
- id: setresponseheader_route |
||||
uri: https://example.org |
||||
filters: |
||||
- SetResponseHeader=X-Response-Red, Blue |
||||
---- |
||||
|
||||
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` `GatewayFilter` 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} |
||||
---- |
||||
|
@ -0,0 +1,40 @@
@@ -0,0 +1,40 @@
|
||||
[[the-setstatus-gatewayfilter-factory]] |
||||
= The `SetStatus` `GatewayFilter` Factory |
||||
|
||||
The `SetStatus` `GatewayFilter` factory 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` `GatewayFilter`: |
||||
|
||||
.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 |
||||
---- |
||||
|
||||
In either case, the HTTP status of the response is set to 401. |
||||
|
||||
You can configure the `SetStatus` `GatewayFilter` to return the original HTTP status code from the proxied request in a header in the response. |
||||
The header is added to the response if configured with the following property: |
||||
|
||||
.application.yml |
||||
[source,yaml] |
||||
---- |
||||
spring: |
||||
cloud: |
||||
gateway: |
||||
set-status: |
||||
original-status-header-name: original-http-status |
||||
---- |
||||
|
@ -0,0 +1,24 @@
@@ -0,0 +1,24 @@
|
||||
[[the-stripprefix-gatewayfilter-factory]] |
||||
= The `StripPrefix` `GatewayFilter` Factory |
||||
|
||||
The `StripPrefix` `GatewayFilter` factory 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` `GatewayFilter`: |
||||
|
||||
.application.yml |
||||
[source,yaml] |
||||
---- |
||||
spring: |
||||
cloud: |
||||
gateway: |
||||
routes: |
||||
- id: nameRoot |
||||
uri: https://nameservice |
||||
predicates: |
||||
- Path=/name/** |
||||
filters: |
||||
- StripPrefix=2 |
||||
---- |
||||
|
||||
When a request is made through the gateway to `/name/blue/red`, the request made to `nameservice` looks like `https://nameservice/red`. |
||||
|
@ -0,0 +1,103 @@
@@ -0,0 +1,103 @@
|
||||
[[the-tokenrelay-gatewayfilter-factory]] |
||||
= The `TokenRelay` `GatewayFilter` Factory |
||||
|
||||
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` `GatewayFilter`. |
||||
|
||||
The `TokenRelay` `GatewayFilter` takes one optional parameter, `clientRegistrationId`. |
||||
The following example configures a `TokenRelay` `GatewayFilter`: |
||||
|
||||
.App.java |
||||
[source,java] |
||||
---- |
||||
|
||||
@Bean |
||||
public RouteLocator customRouteLocator(RouteLocatorBuilder builder) { |
||||
return builder.routes() |
||||
.route("resource", r -> r.path("/resource") |
||||
.filters(f -> f.tokenRelay("myregistrationid")) |
||||
.uri("http://localhost:9000")) |
||||
.build(); |
||||
} |
||||
---- |
||||
|
||||
or this |
||||
|
||||
.application.yaml |
||||
[source,yaml] |
||||
---- |
||||
spring: |
||||
cloud: |
||||
gateway: |
||||
routes: |
||||
- id: resource |
||||
uri: http://localhost:9000 |
||||
predicates: |
||||
- Path=/resource |
||||
filters: |
||||
- TokenRelay=myregistrationid |
||||
---- |
||||
|
||||
The example above specifies a `clientRegistrationId`, which can be used to obtain and forward an OAuth2 access token for any available `ClientRegistration`. |
||||
|
||||
Spring Cloud Gateway can also forward the OAuth2 access token of the currently authenticated user `oauth2Login()` is used to authenticate the user. |
||||
To add this functionality to the gateway, you can omit the `clientRegistrationId` parameter like this: |
||||
|
||||
.App.java |
||||
[source,java] |
||||
---- |
||||
|
||||
@Bean |
||||
public RouteLocator customRouteLocator(RouteLocatorBuilder builder) { |
||||
return builder.routes() |
||||
.route("resource", r -> r.path("/resource") |
||||
.filters(f -> f.tokenRelay()) |
||||
.uri("http://localhost:9000")) |
||||
.build(); |
||||
} |
||||
---- |
||||
|
||||
or this |
||||
|
||||
.application.yaml |
||||
[source,yaml] |
||||
---- |
||||
spring: |
||||
cloud: |
||||
gateway: |
||||
routes: |
||||
- id: resource |
||||
uri: http://localhost:9000 |
||||
predicates: |
||||
- Path=/resource |
||||
filters: |
||||
- TokenRelay= |
||||
---- |
||||
|
||||
and it will (in addition to logging the user in and grabbing a token) |
||||
pass the authentication token downstream to the services (in this case |
||||
`/resource`). |
||||
|
||||
To enable this for Spring Cloud Gateway add the following dependencies |
||||
|
||||
- `org.springframework.boot:spring-boot-starter-oauth2-client` |
||||
|
||||
How does it work? The {github-code}/src/main/java/org/springframework/cloud/gateway/security/TokenRelayGatewayFilterFactory.java[filter] |
||||
extracts an OAuth2 access token from the currently authenticated user for the provided `clientRegistrationId`. |
||||
If no `clientRegistrationId` is provided, the currently authenticated user's own access token (obtained during login) is used. |
||||
In either case, the extracted access token is placed in a request header for the downstream requests. |
||||
|
||||
For a full working sample see https://github.com/spring-cloud-samples/sample-gateway-oauth2login[this project]. |
||||
|
||||
NOTE: A `TokenRelayGatewayFilterFactory` bean will only be created if the proper `spring.security.oauth2.client.*` properties are set which will trigger creation of a `ReactiveClientRegistrationRepository` bean. |
||||
|
||||
NOTE: The default implementation of `ReactiveOAuth2AuthorizedClientService` used by `TokenRelayGatewayFilterFactory` |
||||
uses an in-memory data store. You will need to provide your own implementation `ReactiveOAuth2AuthorizedClientService` |
||||
if you need a more robust solution. |
||||
|
||||
|
@ -0,0 +1,200 @@
@@ -0,0 +1,200 @@
|
||||
[[global-filters]] |
||||
= Global Filters |
||||
|
||||
The `GlobalFilter` interface has the same signature as `GatewayFilter`. |
||||
These are special filters that are conditionally applied to all routes. |
||||
|
||||
NOTE: This interface and its usage are subject to change in future milestone releases. |
||||
|
||||
[[gateway-combined-global-filter-and-gatewayfilter-ordering]] |
||||
== Combined Global Filter and `GatewayFilter` Ordering |
||||
|
||||
When a request matches a route, the filtering web handler adds all instances of `GlobalFilter` and all route-specific instances of `GatewayFilter` to a filter chain. |
||||
This combined filter chain is sorted by the `org.springframework.core.Ordered` interface, which you can set by implementing the `getOrder()` method. |
||||
|
||||
As Spring Cloud Gateway distinguishes between "`pre`" and "`post`" phases for filter logic execution (see xref:spring-cloud-gateway/how-it-works.adoc[How it Works]), the filter with the highest precedence is the first in the "`pre`"-phase and the last in the "`post`"-phase. |
||||
|
||||
The following listing configures a filter chain: |
||||
|
||||
.ExampleConfiguration.java |
||||
[source,java] |
||||
---- |
||||
@Bean |
||||
public GlobalFilter customFilter() { |
||||
return new CustomGlobalFilter(); |
||||
} |
||||
|
||||
public class CustomGlobalFilter implements GlobalFilter, Ordered { |
||||
|
||||
@Override |
||||
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) { |
||||
log.info("custom global filter"); |
||||
return chain.filter(exchange); |
||||
} |
||||
|
||||
@Override |
||||
public int getOrder() { |
||||
return -1; |
||||
} |
||||
} |
||||
---- |
||||
|
||||
[[the-gateway-metrics-filter]] |
||||
== The Gateway Metrics Filter |
||||
|
||||
To enable gateway metrics, add `spring-boot-starter-actuator` as a project dependency. Then, by default, the gateway metrics filter runs as long as the `spring.cloud.gateway.metrics.enabled` property is not set to `false`. |
||||
This filter adds a timer metric named `spring.cloud.gateway.requests` with the following tags: |
||||
|
||||
* `routeId`: The route ID. |
||||
* `routeUri`: The URI to which the API is routed. |
||||
* `outcome`: The outcome, as classified by link:https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/http/HttpStatus.Series.html[HttpStatus.Series]. |
||||
* `status`: The HTTP status of the request returned to the client. |
||||
* `httpStatusCode`: The HTTP Status of the request returned to the client. |
||||
* `httpMethod`: The HTTP method used for the request. |
||||
|
||||
In addition, through the `spring.cloud.gateway.metrics.tags.path.enabled` property (by default, `false`), you can activate an extra metric with the path tag: |
||||
|
||||
* `path`: The path of the request. |
||||
|
||||
These metrics are then available to be scraped from `/actuator/metrics/spring.cloud.gateway.requests` and can be easily integrated with Prometheus to create a link:images/gateway-grafana-dashboard.jpeg[Grafana] link:gateway-grafana-dashboard.json[dashboard]. |
||||
|
||||
NOTE: To enable the prometheus endpoint, add `micrometer-registry-prometheus` as a project dependency. |
||||
|
||||
[[local-cache-response-global-filter]] |
||||
== The Local Response Cache Filter |
||||
|
||||
The `LocalResponseCache` runs if associated properties are enabled: |
||||
|
||||
* `spring.cloud.gateway.global-filter.local-response-cache.enabled`: Activates the global cache for all routes |
||||
* `spring.cloud.gateway.filter.local-response-cache.enabled`: Activates the associated filter to use at route level |
||||
|
||||
This feature enables a local cache using Caffeine for all responses that meet the following criteria: |
||||
|
||||
* The request is a bodiless GET. |
||||
* The response has one of the following status codes: HTTP 200 (OK), HTTP 206 (Partial Content), or HTTP 301 (Moved Permanently). |
||||
* The HTTP `Cache-Control` header allows caching (that means it does not have any of the following values: `no-store` present in the request and `no-store` or `private` present in the response). |
||||
|
||||
It accepts two configuration parameters: |
||||
|
||||
* `spring.cloud.gateway.filter.local-response-cache.size`: Sets the maximum size of the cache to evict entries for this route (in KB, MB and GB). |
||||
* `spring.cloud.gateway.filter.local-response-cache.time-to-live` Sets the time to expire a cache entry (expressed in s for seconds, m for minutes, and h for hours). |
||||
|
||||
If none of these parameters are configured but the global filter is enabled, by default, it configures 5 minutes of time to live for the cached response. |
||||
|
||||
This filter also implements the automatic calculation of the `max-age` value in the HTTP `Cache-Control` header. |
||||
If `max-age` is present on the original response, the value is rewritten with the number of seconds set in the `timeToLive` configuration parameter. |
||||
In subsequent calls, this value is recalculated with the number of seconds left until the response expires. |
||||
|
||||
Setting `spring.cloud.gateway.global-filter.local-response-cache.enabled` to `false` deactivate the local response cache for all routes, the xref:spring-cloud-gateway/gatewayfilter-factories/local-cache-response-filter.adoc[LocalResponseCache filter] allows to use this functionality at route level. |
||||
|
||||
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`. |
||||
|
||||
[[forward-routing-filter]] |
||||
== Forward Routing Filter |
||||
|
||||
The `ForwardRoutingFilter` looks for a URI in the exchange attribute `ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR`. |
||||
If the URL has a `forward` scheme (such as `forward:///localendpoint`), it uses the Spring `DispatcherHandler` to handle the request. |
||||
The path part of the request URL is overridden with the path in the forward URL. |
||||
The unmodified original URL is appended to the list in the `ServerWebExchangeUtils.GATEWAY_ORIGINAL_REQUEST_URL_ATTR` attribute. |
||||
|
||||
[[the-netty-routing-filter]] |
||||
== The Netty Routing Filter |
||||
|
||||
The Netty routing filter runs if the URL located in the `ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR` exchange attribute has a `http` or `https` scheme. |
||||
It uses the Netty `HttpClient` to make the downstream proxy request. |
||||
The response is put in the `ServerWebExchangeUtils.CLIENT_RESPONSE_ATTR` exchange attribute for use in a later filter. |
||||
(There is also an experimental `WebClientHttpRoutingFilter` that performs the same function but does not require Netty.) |
||||
|
||||
[[the-netty-write-response-filter]] |
||||
== The Netty Write Response Filter |
||||
|
||||
The `NettyWriteResponseFilter` runs if there is a Netty `HttpClientResponse` in the `ServerWebExchangeUtils.CLIENT_RESPONSE_ATTR` exchange attribute. |
||||
It runs after all other filters have completed and writes the proxy response back to the gateway client response. |
||||
(There is also an experimental `WebClientWriteResponseFilter` that performs the same function but does not require Netty.) |
||||
|
||||
[[reactive-loadbalancer-client-filter]] |
||||
== The `ReactiveLoadBalancerClientFilter` |
||||
|
||||
The `ReactiveLoadBalancerClientFilter` looks for a URI in the exchange attribute named `ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR`. |
||||
If the URL has a `lb` scheme (such as `lb://myservice`), it uses the Spring Cloud `ReactorLoadBalancer` to resolve the name (`myservice` in this example) to an actual host and port and replaces the URI in the same attribute. |
||||
The unmodified original URL is appended to the list in the `ServerWebExchangeUtils.GATEWAY_ORIGINAL_REQUEST_URL_ATTR` attribute. |
||||
The filter also looks in the `ServerWebExchangeUtils.GATEWAY_SCHEME_PREFIX_ATTR` attribute to see if it equals `lb`. |
||||
If so, the same rules apply. |
||||
The following listing configures a `ReactiveLoadBalancerClientFilter`: |
||||
|
||||
.application.yml |
||||
[source,yaml] |
||||
---- |
||||
spring: |
||||
cloud: |
||||
gateway: |
||||
routes: |
||||
- id: myRoute |
||||
uri: lb://service |
||||
predicates: |
||||
- Path=/service/** |
||||
---- |
||||
|
||||
NOTE: By default, when a service instance cannot be found by the `ReactorLoadBalancer`, a `503` is returned. |
||||
You can configure the gateway to return a `404` by setting `spring.cloud.gateway.loadbalancer.use404=true`. |
||||
|
||||
NOTE: The `isSecure` value of the `ServiceInstance` returned from the `ReactiveLoadBalancerClientFilter` overrides |
||||
the scheme specified in the request made to the Gateway. |
||||
For example, if the request comes into the Gateway over `HTTPS` but the `ServiceInstance` indicates it is not secure, the downstream request is made over `HTTP`. |
||||
The opposite situation can also apply. |
||||
However, if `GATEWAY_SCHEME_PREFIX_ATTR` is specified for the route in the Gateway configuration, the prefix is stripped and the resulting scheme from the route URL overrides the `ServiceInstance` configuration. |
||||
|
||||
TIP: Gateway supports all the LoadBalancer features. You can read more about them in the https://docs.spring.io/spring-cloud-commons/docs/current/reference/html/#spring-cloud-loadbalancer[Spring Cloud Commons documentation]. |
||||
|
||||
[[the-routetorequesturl-filter]] |
||||
== The `RouteToRequestUrl` Filter |
||||
|
||||
If there is a `Route` object in the `ServerWebExchangeUtils.GATEWAY_ROUTE_ATTR` exchange attribute, the `RouteToRequestUrlFilter` runs. |
||||
It creates a new URI, based off of the request URI but updated with the URI attribute of the `Route` object. |
||||
The new URI is placed in the `ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR` exchange attribute. |
||||
|
||||
If the URI has a scheme prefix, such as `lb:ws://serviceid`, the `lb` scheme is stripped from the URI and placed in the `ServerWebExchangeUtils.GATEWAY_SCHEME_PREFIX_ATTR` for use later in the filter chain. |
||||
|
||||
[[the-websocket-routing-filter]] |
||||
== The Websocket Routing Filter |
||||
|
||||
If the URL located in the `ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR` exchange attribute has a `ws` or `wss` scheme, the websocket routing filter runs. It uses the Spring WebSocket infrastructure to forward the websocket request downstream. |
||||
|
||||
You can load-balance websockets by prefixing the URI with `lb`, such as `lb:ws://serviceid`. |
||||
|
||||
NOTE: If you use https://github.com/sockjs[SockJS] as a fallback over normal HTTP, you should configure a normal HTTP route as well as the websocket Route. |
||||
|
||||
The following listing configures a websocket routing filter: |
||||
|
||||
.application.yml |
||||
[source,yaml] |
||||
---- |
||||
spring: |
||||
cloud: |
||||
gateway: |
||||
routes: |
||||
# SockJS route |
||||
- id: websocket_sockjs_route |
||||
uri: http://localhost:3001 |
||||
predicates: |
||||
- Path=/websocket/info/** |
||||
# Normal Websocket route |
||||
- id: websocket_route |
||||
uri: ws://localhost:3001 |
||||
predicates: |
||||
- Path=/websocket/** |
||||
---- |
||||
|
||||
[[marking-an-exchange-as-routed]] |
||||
== Marking An Exchange As Routed |
||||
|
||||
After the gateway has routed a `ServerWebExchange`, it marks that exchange as "`routed`" by adding `gatewayAlreadyRouted` |
||||
to the exchange attributes. Once a request has been marked as routed, other routing filters will not route the request again, |
||||
essentially skipping the filter. There are convenience methods that you can use to mark an exchange as routed |
||||
or check if an exchange has already been routed. |
||||
|
||||
* `ServerWebExchangeUtils.isAlreadyRouted` takes a `ServerWebExchange` object and checks if it has been "`routed`". |
||||
* `ServerWebExchangeUtils.setAlreadyRouted` takes a `ServerWebExchange` object and marks it as "`routed`". |
||||
|
@ -0,0 +1,11 @@
@@ -0,0 +1,11 @@
|
||||
[[glossary]] |
||||
= Glossary |
||||
:page-section-summary-toc: 1 |
||||
|
||||
* *Route*: The basic building block of the gateway. |
||||
It is defined by an ID, a destination URI, a collection of predicates, and a collection of filters. A route is matched if the aggregate predicate is true. |
||||
* *Predicate*: This is a https://docs.oracle.com/javase/8/docs/api/java/util/function/Predicate.html[Java 8 Function Predicate]. The input type is a https://docs.spring.io/spring/docs/5.0.x/javadoc-api/org/springframework/web/server/ServerWebExchange.html[Spring Framework `ServerWebExchange`]. |
||||
This lets you match on anything from the HTTP request, such as headers or parameters. |
||||
* *Filter*: These are instances of {github-code}/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/filter/GatewayFilter.java[`GatewayFilter`] that have been constructed with a specific factory. |
||||
Here, you can modify requests and responses before or after sending the downstream request. |
||||
|
@ -0,0 +1,15 @@
@@ -0,0 +1,15 @@
|
||||
[[gateway-how-it-works]] |
||||
= How It Works |
||||
:page-section-summary-toc: 1 |
||||
|
||||
The following diagram provides a high-level overview of how Spring Cloud Gateway works: |
||||
|
||||
image::spring_cloud_gateway_diagram.png[Spring Cloud Gateway Diagram] |
||||
|
||||
Clients make requests to Spring Cloud Gateway. If the Gateway Handler Mapping determines that a request matches a route, it is sent to the Gateway Web Handler. |
||||
This handler runs the request through a filter chain that is specific to the request. |
||||
The reason the filters are divided by the dotted line is that filters can run logic both before and after the proxy request is sent. |
||||
All "`pre`" filter logic is executed. Then the proxy request is made. After the proxy request is made, the "`post`" filter logic is run. |
||||
|
||||
NOTE: URIs defined in routes without a port get default port values of 80 and 443 for the HTTP and HTTPS URIs, respectively. |
||||
|
@ -0,0 +1,75 @@
@@ -0,0 +1,75 @@
|
||||
[[http-timeouts-configuration]] |
||||
= Http timeouts configuration |
||||
|
||||
Http timeouts (response and connect) can be configured for all routes and overridden for each specific route. |
||||
|
||||
[[global-timeouts]] |
||||
== Global timeouts |
||||
To configure Global http timeouts: + |
||||
`connect-timeout` must be specified in milliseconds. + |
||||
`response-timeout` must be specified as a java.time.Duration |
||||
|
||||
.global http timeouts example |
||||
[source,yaml] |
||||
---- |
||||
spring: |
||||
cloud: |
||||
gateway: |
||||
httpclient: |
||||
connect-timeout: 1000 |
||||
response-timeout: 5s |
||||
---- |
||||
|
||||
[[per-route-timeouts]] |
||||
== Per-route timeouts |
||||
To configure per-route timeouts: + |
||||
`connect-timeout` must be specified in milliseconds. + |
||||
`response-timeout` must be specified in milliseconds. |
||||
|
||||
.per-route http timeouts configuration via configuration |
||||
[source,yaml] |
||||
---- |
||||
- id: per_route_timeouts |
||||
uri: https://example.org |
||||
predicates: |
||||
- name: Path |
||||
args: |
||||
pattern: /delay/{timeout} |
||||
metadata: |
||||
response-timeout: 200 |
||||
connect-timeout: 200 |
||||
---- |
||||
|
||||
.per-route timeouts configuration using Java DSL |
||||
[source,java] |
||||
---- |
||||
import static org.springframework.cloud.gateway.support.RouteMetadataUtils.CONNECT_TIMEOUT_ATTR; |
||||
import static org.springframework.cloud.gateway.support.RouteMetadataUtils.RESPONSE_TIMEOUT_ATTR; |
||||
|
||||
@Bean |
||||
public RouteLocator customRouteLocator(RouteLocatorBuilder routeBuilder){ |
||||
return routeBuilder.routes() |
||||
.route("test1", r -> { |
||||
return r.host("*.somehost.org").and().path("/somepath") |
||||
.filters(f -> f.addRequestHeader("header1", "header-value-1")) |
||||
.uri("http://someuri") |
||||
.metadata(RESPONSE_TIMEOUT_ATTR, 200) |
||||
.metadata(CONNECT_TIMEOUT_ATTR, 200); |
||||
}) |
||||
.build(); |
||||
} |
||||
---- |
||||
|
||||
A per-route `response-timeout` with a negative value will disable the global `response-timeout` value. |
||||
|
||||
---- |
||||
- id: per_route_timeouts |
||||
uri: https://example.org |
||||
predicates: |
||||
- name: Path |
||||
args: |
||||
pattern: /delay/{timeout} |
||||
metadata: |
||||
response-timeout: -1 |
||||
---- |
||||
|
@ -0,0 +1,45 @@
@@ -0,0 +1,45 @@
|
||||
[[httpheadersfilters]] |
||||
= HttpHeadersFilters |
||||
|
||||
`HttpHeadersFilters` are applied to the requests before sending them downstream, such as in the `NettyRoutingFilter`. |
||||
|
||||
[[forwarded-headers-filter]] |
||||
== Forwarded Headers Filter |
||||
The `Forwarded` Headers Filter creates a `Forwarded` header to send to the downstream service. It adds the `Host` header, scheme and port of the current request to any existing `Forwarded` header. |
||||
|
||||
[[removehopbyhop-headers-filter]] |
||||
== RemoveHopByHop Headers Filter |
||||
The `RemoveHopByHop` Headers Filter removes headers from forwarded requests. The default list of headers that is removed comes from the https://tools.ietf.org/html/draft-ietf-httpbis-p1-messaging-14#section-7.1.3[IETF]. |
||||
|
||||
.The default removed headers are: |
||||
* Connection |
||||
* Keep-Alive |
||||
* Proxy-Authenticate |
||||
* Proxy-Authorization |
||||
* TE |
||||
* Trailer |
||||
* Transfer-Encoding |
||||
* Upgrade |
||||
|
||||
To change this, set the `spring.cloud.gateway.filter.remove-hop-by-hop.headers` property to the list of header names to remove. |
||||
|
||||
[[xforwarded-headers-filter]] |
||||
== XForwarded Headers Filter |
||||
The `XForwarded` Headers Filter creates various `X-Forwarded-*` headers to send to the downstream service. It uses the `Host` header, scheme, port and path of the current request to create the various headers. |
||||
|
||||
Creating of individual headers can be controlled by the following boolean properties (defaults to true): |
||||
|
||||
- `spring.cloud.gateway.x-forwarded.for-enabled` |
||||
- `spring.cloud.gateway.x-forwarded.host-enabled` |
||||
- `spring.cloud.gateway.x-forwarded.port-enabled` |
||||
- `spring.cloud.gateway.x-forwarded.proto-enabled` |
||||
- `spring.cloud.gateway.x-forwarded.prefix-enabled` |
||||
|
||||
Appending multiple headers can be controlled by the following boolean properties (defaults to true): |
||||
|
||||
- `spring.cloud.gateway.x-forwarded.for-append` |
||||
- `spring.cloud.gateway.x-forwarded.host-append` |
||||
- `spring.cloud.gateway.x-forwarded.port-append` |
||||
- `spring.cloud.gateway.x-forwarded.proto-append` |
||||
- `spring.cloud.gateway.x-forwarded.prefix-append` |
||||
|
@ -0,0 +1,27 @@
@@ -0,0 +1,27 @@
|
||||
[[reactor-netty-access-logs]] |
||||
= Reactor Netty Access Logs |
||||
|
||||
To enable Reactor Netty access logs, set `-Dreactor.netty.http.server.accessLogEnabled=true`. |
||||
|
||||
IMPORTANT: It must be a Java System Property, not a Spring Boot property. |
||||
|
||||
You can configure the logging system to have a separate access log file. The following example creates a Logback configuration: |
||||
|
||||
.logback.xml |
||||
[source,xml] |
||||
---- |
||||
<appender name="accessLog" class="ch.qos.logback.core.FileAppender"> |
||||
<file>access_log.log</file> |
||||
<encoder> |
||||
<pattern>%msg%n</pattern> |
||||
</encoder> |
||||
</appender> |
||||
<appender name="async" class="ch.qos.logback.classic.AsyncAppender"> |
||||
<appender-ref ref="accessLog" /> |
||||
</appender> |
||||
|
||||
<logger name="reactor.netty.http.server.AccessLog" level="INFO" additivity="false"> |
||||
<appender-ref ref="async"/> |
||||
</logger> |
||||
---- |
||||
|
@ -0,0 +1,376 @@
@@ -0,0 +1,376 @@
|
||||
[[gateway-request-predicates-factories]] |
||||
= Route Predicate Factories |
||||
|
||||
Spring Cloud Gateway matches routes as part of the Spring WebFlux `HandlerMapping` infrastructure. |
||||
Spring Cloud Gateway includes many built-in route predicate factories. |
||||
All of these predicates match on different attributes of the HTTP request. |
||||
You can combine multiple route predicate factories with logical `and` statements. |
||||
|
||||
[[the-after-route-predicate-factory]] |
||||
== The After Route Predicate Factory |
||||
|
||||
The `After` route predicate factory takes one parameter, a `datetime` (which is a java `ZonedDateTime`). |
||||
This predicate matches requests that happen after the specified datetime. |
||||
The following example configures an after route predicate: |
||||
|
||||
.application.yml |
||||
[source,yaml] |
||||
---- |
||||
spring: |
||||
cloud: |
||||
gateway: |
||||
routes: |
||||
- id: after_route |
||||
uri: https://example.org |
||||
predicates: |
||||
- After=2017-01-20T17:42:47.789-07:00[America/Denver] |
||||
---- |
||||
|
||||
This route matches any request made after Jan 20, 2017 17:42 Mountain Time (Denver). |
||||
|
||||
[[the-before-route-predicate-factory]] |
||||
== The Before Route Predicate Factory |
||||
|
||||
The `Before` route predicate factory takes one parameter, a `datetime` (which is a java `ZonedDateTime`). |
||||
This predicate matches requests that happen before the specified `datetime`. |
||||
The following example configures a before route predicate: |
||||
|
||||
.application.yml |
||||
[source,yaml] |
||||
---- |
||||
spring: |
||||
cloud: |
||||
gateway: |
||||
routes: |
||||
- id: before_route |
||||
uri: https://example.org |
||||
predicates: |
||||
- Before=2017-01-20T17:42:47.789-07:00[America/Denver] |
||||
---- |
||||
|
||||
This route matches any request made before Jan 20, 2017 17:42 Mountain Time (Denver). |
||||
|
||||
[[the-between-route-predicate-factory]] |
||||
== The Between Route Predicate Factory |
||||
|
||||
The `Between` route predicate factory takes two parameters, `datetime1` and `datetime2` |
||||
which are java `ZonedDateTime` objects. |
||||
This predicate matches requests that happen after `datetime1` and before `datetime2`. |
||||
The `datetime2` parameter must be after `datetime1`. |
||||
The following example configures a between route predicate: |
||||
|
||||
.application.yml |
||||
[source,yaml] |
||||
---- |
||||
spring: |
||||
cloud: |
||||
gateway: |
||||
routes: |
||||
- id: between_route |
||||
uri: https://example.org |
||||
predicates: |
||||
- Between=2017-01-20T17:42:47.789-07:00[America/Denver], 2017-01-21T17:42:47.789-07:00[America/Denver] |
||||
---- |
||||
|
||||
This route matches any request made after Jan 20, 2017 17:42 Mountain Time (Denver) and before Jan 21, 2017 17:42 Mountain Time (Denver). |
||||
This could be useful for maintenance windows. |
||||
|
||||
[[the-cookie-route-predicate-factory]] |
||||
== The Cookie Route Predicate Factory |
||||
|
||||
The `Cookie` route predicate factory takes two parameters, the cookie `name` and a `regexp` (which is a Java regular expression). |
||||
This predicate matches cookies that have the given name and whose values match the regular expression. |
||||
The following example configures a cookie route predicate factory: |
||||
|
||||
.application.yml |
||||
[source,yaml] |
||||
---- |
||||
spring: |
||||
cloud: |
||||
gateway: |
||||
routes: |
||||
- id: cookie_route |
||||
uri: https://example.org |
||||
predicates: |
||||
- Cookie=chocolate, ch.p |
||||
---- |
||||
|
||||
This route matches requests that have a cookie named `chocolate` whose value matches the `ch.p` regular expression. |
||||
|
||||
[[the-header-route-predicate-factory]] |
||||
== The Header Route Predicate Factory |
||||
|
||||
The `Header` route predicate factory takes two parameters, the `header` and a `regexp` (which is a Java regular expression). |
||||
This predicate matches with a header that has the given name whose value matches the regular expression. |
||||
The following example configures a header route predicate: |
||||
|
||||
.application.yml |
||||
[source,yaml] |
||||
---- |
||||
spring: |
||||
cloud: |
||||
gateway: |
||||
routes: |
||||
- id: header_route |
||||
uri: https://example.org |
||||
predicates: |
||||
- Header=X-Request-Id, \d+ |
||||
---- |
||||
|
||||
This route matches if the request has a header named `X-Request-Id` whose value matches the `\d+` regular expression (that is, it has a value of one or more digits). |
||||
|
||||
[[the-host-route-predicate-factory]] |
||||
== The Host Route Predicate Factory |
||||
|
||||
The `Host` route predicate factory takes one parameter: a list of host name `patterns`. |
||||
The pattern is an Ant-style pattern with `.` as the separator. |
||||
This predicates matches the `Host` header that matches the pattern. |
||||
The following example configures a host route predicate: |
||||
|
||||
.application.yml |
||||
[source,yaml] |
||||
---- |
||||
spring: |
||||
cloud: |
||||
gateway: |
||||
routes: |
||||
- id: host_route |
||||
uri: https://example.org |
||||
predicates: |
||||
- Host=**.somehost.org,**.anotherhost.org |
||||
---- |
||||
|
||||
URI template variables (such as `\{sub}.myhost.org`) are supported as well. |
||||
|
||||
This route matches if the request has a `Host` header with a value of `www.somehost.org` or `beta.somehost.org` or `www.anotherhost.org`. |
||||
|
||||
This predicate extracts the URI template variables (such as `sub`, defined in the preceding example) as a map of names and values and places it in the `ServerWebExchange.getAttributes()` with a key defined in `ServerWebExchangeUtils.URI_TEMPLATE_VARIABLES_ATTRIBUTE`. |
||||
Those values are then available for use by <<gateway-route-filters,`GatewayFilter` factories>> |
||||
|
||||
|
||||
[[the-method-route-predicate-factory]] |
||||
== The Method Route Predicate Factory |
||||
|
||||
The `Method` Route Predicate Factory takes a `methods` argument which is one or more parameters: the HTTP methods to match. |
||||
The following example configures a method route predicate: |
||||
|
||||
.application.yml |
||||
[source,yaml] |
||||
---- |
||||
spring: |
||||
cloud: |
||||
gateway: |
||||
routes: |
||||
- id: method_route |
||||
uri: https://example.org |
||||
predicates: |
||||
- Method=GET,POST |
||||
---- |
||||
|
||||
This route matches if the request method was a `GET` or a `POST`. |
||||
|
||||
[[the-path-route-predicate-factory]] |
||||
== The Path Route Predicate Factory |
||||
|
||||
The `Path` Route Predicate Factory takes two parameters: a list of Spring `PathMatcher` `patterns` and an optional flag called `matchTrailingSlash` (defaults to `true`). |
||||
The following example configures a path route predicate: |
||||
|
||||
.application.yml |
||||
[source,yaml] |
||||
---- |
||||
spring: |
||||
cloud: |
||||
gateway: |
||||
routes: |
||||
- id: path_route |
||||
uri: https://example.org |
||||
predicates: |
||||
- Path=/red/{segment},/blue/{segment} |
||||
---- |
||||
|
||||
This route matches if the request path was, for example: `/red/1` or `/red/1/` or `/red/blue` or `/blue/green`. |
||||
|
||||
If `matchTrailingSlash` is set to `false`, then request path `/red/1/` will not be matched. |
||||
|
||||
This predicate extracts the URI template variables (such as `segment`, defined in the preceding example) as a map of names and values and places it in the `ServerWebExchange.getAttributes()` with a key defined in `ServerWebExchangeUtils.URI_TEMPLATE_VARIABLES_ATTRIBUTE`. |
||||
Those values are then available for use by <<gateway-route-filters,`GatewayFilter` factories>> |
||||
|
||||
A utility method (called `get`) is available to make access to these variables easier. |
||||
The following example shows how to use the `get` method: |
||||
|
||||
[source,java] |
||||
---- |
||||
Map<String, String> uriVariables = ServerWebExchangeUtils.getUriTemplateVariables(exchange); |
||||
|
||||
String segment = uriVariables.get("segment"); |
||||
---- |
||||
|
||||
[[the-query-route-predicate-factory]] |
||||
== The Query Route Predicate Factory |
||||
|
||||
The `Query` route predicate factory takes two parameters: a required `param` and an optional `regexp` (which is a Java regular expression). |
||||
The following example configures a query route predicate: |
||||
|
||||
.application.yml |
||||
[source,yaml] |
||||
---- |
||||
spring: |
||||
cloud: |
||||
gateway: |
||||
routes: |
||||
- id: query_route |
||||
uri: https://example.org |
||||
predicates: |
||||
- Query=green |
||||
---- |
||||
|
||||
The preceding route matches if the request contained a `green` query parameter. |
||||
|
||||
.application.yml |
||||
[source,yaml] |
||||
---- |
||||
spring: |
||||
cloud: |
||||
gateway: |
||||
routes: |
||||
- id: query_route |
||||
uri: https://example.org |
||||
predicates: |
||||
- Query=red, gree. |
||||
---- |
||||
|
||||
The preceding route matches if the request contained a `red` query parameter whose value matched the `gree.` regexp, so `green` and `greet` would match. |
||||
|
||||
|
||||
[[the-remoteaddr-route-predicate-factory]] |
||||
== The RemoteAddr Route Predicate Factory |
||||
|
||||
The `RemoteAddr` route predicate factory takes a list (min size 1) of `sources`, which are CIDR-notation (IPv4 or IPv6) strings, such as `192.168.0.1/16` (where `192.168.0.1` is an IP address and `16` is a subnet mask). |
||||
The following example configures a RemoteAddr route predicate: |
||||
|
||||
.application.yml |
||||
[source,yaml] |
||||
---- |
||||
spring: |
||||
cloud: |
||||
gateway: |
||||
routes: |
||||
- id: remoteaddr_route |
||||
uri: https://example.org |
||||
predicates: |
||||
- RemoteAddr=192.168.1.1/24 |
||||
---- |
||||
|
||||
This route matches if the remote address of the request was, for example, `192.168.1.10`. |
||||
|
||||
[[modifying-the-way-remote-addresses-are-resolved]] |
||||
=== Modifying the Way Remote Addresses Are Resolved |
||||
|
||||
By default, the RemoteAddr route predicate factory uses the remote address from the incoming request. |
||||
This may not match the actual client IP address if Spring Cloud Gateway sits behind a proxy layer. |
||||
|
||||
You can customize the way that the remote address is resolved by setting a custom `RemoteAddressResolver`. |
||||
Spring Cloud Gateway comes with one non-default remote address resolver that is based off of the https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-For[X-Forwarded-For header], `XForwardedRemoteAddressResolver`. |
||||
|
||||
`XForwardedRemoteAddressResolver` has two static constructor methods, which take different approaches to security: |
||||
|
||||
* `XForwardedRemoteAddressResolver::trustAll` returns a `RemoteAddressResolver` that always takes the first IP address found in the `X-Forwarded-For` header. |
||||
This approach is vulnerable to spoofing, as a malicious client could set an initial value for the `X-Forwarded-For`, which would be accepted by the resolver. |
||||
|
||||
* `XForwardedRemoteAddressResolver::maxTrustedIndex` takes an index that correlates to the number of trusted infrastructure running in front of Spring Cloud Gateway. |
||||
If Spring Cloud Gateway is, for example only accessible through HAProxy, then a value of 1 should be used. |
||||
If two hops of trusted infrastructure are required before Spring Cloud Gateway is accessible, then a value of 2 should be used. |
||||
|
||||
Consider the following header value: |
||||
|
||||
[source] |
||||
---- |
||||
X-Forwarded-For: 0.0.0.1, 0.0.0.2, 0.0.0.3 |
||||
---- |
||||
|
||||
The following `maxTrustedIndex` values yield the following remote addresses: |
||||
|
||||
[options="header"] |
||||
|=== |
||||
|`maxTrustedIndex` | result |
||||
|[`Integer.MIN_VALUE`,0] | (invalid, `IllegalArgumentException` during initialization) |
||||
|1 | 0.0.0.3 |
||||
|2 | 0.0.0.2 |
||||
|3 | 0.0.0.1 |
||||
|[4, `Integer.MAX_VALUE`] | 0.0.0.1 |
||||
|=== |
||||
|
||||
[[gateway-route-filters]] |
||||
The following example shows how to achieve the same configuration with Java: |
||||
|
||||
.GatewayConfig.java |
||||
[source,java] |
||||
---- |
||||
RemoteAddressResolver resolver = XForwardedRemoteAddressResolver |
||||
.maxTrustedIndex(1); |
||||
|
||||
... |
||||
|
||||
.route("direct-route", |
||||
r -> r.remoteAddr("10.1.1.1", "10.10.1.1/24") |
||||
.uri("https://downstream1") |
||||
.route("proxied-route", |
||||
r -> r.remoteAddr(resolver, "10.10.1.1", "10.10.1.1/24") |
||||
.uri("https://downstream2") |
||||
) |
||||
---- |
||||
|
||||
[[the-weight-route-predicate-factory]] |
||||
== The Weight Route Predicate Factory |
||||
|
||||
The `Weight` route predicate factory takes two arguments: `group` and `weight` (an int). The weights are calculated per group. |
||||
The following example configures a weight route predicate: |
||||
|
||||
.application.yml |
||||
[source,yaml] |
||||
---- |
||||
spring: |
||||
cloud: |
||||
gateway: |
||||
routes: |
||||
- id: weight_high |
||||
uri: https://weighthigh.org |
||||
predicates: |
||||
- Weight=group1, 8 |
||||
- id: weight_low |
||||
uri: https://weightlow.org |
||||
predicates: |
||||
- Weight=group1, 2 |
||||
---- |
||||
|
||||
This route would forward ~80% of traffic to https://weighthigh.org and ~20% of traffic to https://weighlow.org |
||||
|
||||
[[the-xforwarded-remote-addr-route-predicate-factory]] |
||||
== The XForwarded Remote Addr Route Predicate Factory |
||||
|
||||
The `XForwarded Remote Addr` route predicate factory takes a list (min size 1) of `sources`, which are CIDR-notation (IPv4 or IPv6) strings, such as `192.168.0.1/16` (where `192.168.0.1` is an IP address and `16` is a subnet mask). |
||||
|
||||
This route predicate allows requests to be filtered based on the `X-Forwarded-For` HTTP header. |
||||
|
||||
This can be used with reverse proxies such as load balancers or web application firewalls where |
||||
the request should only be allowed if it comes from a trusted list of IP addresses used by those |
||||
reverse proxies. |
||||
|
||||
|
||||
The following example configures a XForwardedRemoteAddr route predicate: |
||||
|
||||
.application.yml |
||||
[source,yaml] |
||||
---- |
||||
spring: |
||||
cloud: |
||||
gateway: |
||||
routes: |
||||
- id: xforwarded_remoteaddr_route |
||||
uri: https://example.org |
||||
predicates: |
||||
- XForwardedRemoteAddr=192.168.1.1/24 |
||||
---- |
||||
|
||||
This route matches if the `X-Forwarded-For` header contains, for example, `192.168.1.10`. |
||||
|
@ -0,0 +1,32 @@
@@ -0,0 +1,32 @@
|
||||
[[route-metadata-configuration]] |
||||
= Route Metadata Configuration |
||||
|
||||
You can configure additional parameters for each route by using metadata, as follows: |
||||
|
||||
.application.yml |
||||
[source,yaml] |
||||
---- |
||||
spring: |
||||
cloud: |
||||
gateway: |
||||
routes: |
||||
- id: route_with_metadata |
||||
uri: https://example.org |
||||
metadata: |
||||
optionName: "OptionValue" |
||||
compositeObject: |
||||
name: "value" |
||||
iAmNumber: 1 |
||||
---- |
||||
|
||||
You could acquire all metadata properties from an exchange, as follows: |
||||
|
||||
[source] |
||||
---- |
||||
Route route = exchange.getAttribute(GATEWAY_ROUTE_ATTR); |
||||
// get all metadata properties |
||||
route.getMetadata(); |
||||
// get a single metadata property |
||||
route.getMetadata(someKey); |
||||
---- |
||||
|
@ -0,0 +1,16 @@
@@ -0,0 +1,16 @@
|
||||
[[gateway-starter]] |
||||
= How to Include Spring Cloud Gateway |
||||
:page-section-summary-toc: 1 |
||||
|
||||
To include Spring Cloud Gateway in your project, use the starter with a group ID of `org.springframework.cloud` and an artifact ID of `spring-cloud-starter-gateway`. |
||||
See the https://projects.spring.io/spring-cloud/[Spring Cloud Project page] for details on setting up your build system with the current Spring Cloud Release Train. |
||||
|
||||
If you include the starter, but you do not want the gateway to be enabled, set `spring.cloud.gateway.enabled=false`. |
||||
|
||||
IMPORTANT: Spring Cloud Gateway is built on https://spring.io/projects/spring-boot#learn[Spring Boot], https://docs.spring.io/spring/docs/current/spring-framework-reference/web-reactive.html[Spring WebFlux], and https://projectreactor.io/docs[Project Reactor]. |
||||
As a consequence, many of the familiar synchronous libraries (Spring Data and Spring Security, for example) and patterns you know may not apply when you use Spring Cloud Gateway. |
||||
If you are unfamiliar with these projects, we suggest you begin by reading their documentation to familiarize yourself with some new concepts before working with Spring Cloud Gateway. |
||||
|
||||
IMPORTANT: Spring Cloud Gateway requires the Netty runtime provided by Spring Boot and Spring Webflux. |
||||
It does not work in a traditional Servlet Container or when built as a WAR. |
||||
|
@ -0,0 +1,36 @@
@@ -0,0 +1,36 @@
|
||||
[[the-discoveryclient-route-definition-locator]] |
||||
= The `DiscoveryClient` Route Definition Locator |
||||
|
||||
You can configure the gateway to create routes based on services registered with a `DiscoveryClient` compatible service registry. |
||||
|
||||
To enable this, set `spring.cloud.gateway.discovery.locator.enabled=true` and make sure a `DiscoveryClient` implementation (such as Netflix Eureka, Consul, or Zookeeper) is on the classpath and enabled. |
||||
|
||||
[[configuring-predicates-and-filters-for-discoveryclient-routes]] |
||||
== Configuring Predicates and Filters For `DiscoveryClient` Routes |
||||
|
||||
By default, the gateway defines a single predicate and filter for routes created with a `DiscoveryClient`. |
||||
|
||||
The default predicate is a path predicate defined with the pattern `/serviceId/**`, where `serviceId` is |
||||
the ID of the service from the `DiscoveryClient`. |
||||
|
||||
The default filter is a rewrite path filter with the regex `/serviceId/?(?<remaining>.*)` and the replacement `/$\{remaining}`. |
||||
This strips the service ID from the path before the request is sent downstream. |
||||
|
||||
If you want to customize the predicates or filters used by the `DiscoveryClient` routes, set `spring.cloud.gateway.discovery.locator.predicates[x]` and `spring.cloud.gateway.discovery.locator.filters[y]`. |
||||
When doing so, you need to make sure to include the default predicate and filter shown earlier, if you want to retain that functionality. |
||||
The following example shows what this looks like: |
||||
|
||||
.application.properties |
||||
[soure,properties] |
||||
---- |
||||
spring.cloud.gateway.discovery.locator.predicates[0].name: Path |
||||
spring.cloud.gateway.discovery.locator.predicates[0].args[pattern]: "'/'+serviceId+'/**'" |
||||
spring.cloud.gateway.discovery.locator.predicates[1].name: Host |
||||
spring.cloud.gateway.discovery.locator.predicates[1].args[pattern]: "'**.foo.com'" |
||||
spring.cloud.gateway.discovery.locator.filters[0].name: CircuitBreaker |
||||
spring.cloud.gateway.discovery.locator.filters[0].args[name]: serviceId |
||||
spring.cloud.gateway.discovery.locator.filters[1].name: RewritePath |
||||
spring.cloud.gateway.discovery.locator.filters[1].args[regexp]: "'/' + serviceId + '/?(?<remaining>.*)'" |
||||
spring.cloud.gateway.discovery.locator.filters[1].args[replacement]: "'/$\{remaining}'" |
||||
---- |
||||
|
@ -0,0 +1,71 @@
@@ -0,0 +1,71 @@
|
||||
[[tls-and-ssl]] |
||||
= TLS and SSL |
||||
|
||||
The gateway can listen for requests on HTTPS by following the usual Spring server configuration. |
||||
The following example shows how to do so: |
||||
|
||||
.application.yml |
||||
[source,yaml] |
||||
---- |
||||
server: |
||||
ssl: |
||||
enabled: true |
||||
key-alias: scg |
||||
key-store-password: scg1234 |
||||
key-store: classpath:scg-keystore.p12 |
||||
key-store-type: PKCS12 |
||||
---- |
||||
|
||||
You can route gateway routes to both HTTP and HTTPS backends. |
||||
If you are routing to an HTTPS backend, you can configure the gateway to trust all downstream certificates with the following configuration: |
||||
|
||||
.application.yml |
||||
[source,yaml] |
||||
---- |
||||
spring: |
||||
cloud: |
||||
gateway: |
||||
httpclient: |
||||
ssl: |
||||
useInsecureTrustManager: true |
||||
---- |
||||
|
||||
Using an insecure trust manager is not suitable for production. |
||||
For a production deployment, you can configure the gateway with a set of known certificates that it can trust with the following configuration: |
||||
|
||||
.application.yml |
||||
[source,yaml] |
||||
---- |
||||
spring: |
||||
cloud: |
||||
gateway: |
||||
httpclient: |
||||
ssl: |
||||
trustedX509Certificates: |
||||
- cert1.pem |
||||
- cert2.pem |
||||
---- |
||||
|
||||
If the Spring Cloud Gateway is not provisioned with trusted certificates, the default trust store is used (which you can override by setting the `javax.net.ssl.trustStore` system property). |
||||
|
||||
[[tls-handshake]] |
||||
== TLS Handshake |
||||
|
||||
The gateway maintains a client pool that it uses to route to backends. |
||||
When communicating over HTTPS, the client initiates a TLS handshake. |
||||
A number of timeouts are associated with this handshake. |
||||
You can configure these timeouts can be configured (defaults shown) as follows: |
||||
|
||||
.application.yml |
||||
[source,yaml] |
||||
---- |
||||
spring: |
||||
cloud: |
||||
gateway: |
||||
httpclient: |
||||
ssl: |
||||
handshake-timeout-millis: 10000 |
||||
close-notify-flush-timeout-millis: 3000 |
||||
close-notify-read-timeout-millis: 0 |
||||
---- |
||||
|
@ -0,0 +1,25 @@
@@ -0,0 +1,25 @@
|
||||
[[troubleshooting]] |
||||
= Troubleshooting |
||||
:page-section-summary-toc: 1 |
||||
|
||||
This section covers common problems that may arise when you use Spring Cloud Gateway. |
||||
|
||||
[[log-levels]] |
||||
== Log Levels |
||||
|
||||
The following loggers may contain valuable troubleshooting information at the `DEBUG` and `TRACE` levels: |
||||
|
||||
- `org.springframework.cloud.gateway` |
||||
- `org.springframework.http.server.reactive` |
||||
- `org.springframework.web.reactive` |
||||
- `org.springframework.boot.autoconfigure.web` |
||||
- `reactor.netty` |
||||
- `redisratelimiter` |
||||
|
||||
[[wiretap]] |
||||
== Wiretap |
||||
|
||||
The Reactor Netty `HttpClient` and `HttpServer` can have wiretap enabled. |
||||
When combined with setting the `reactor.netty` log level to `DEBUG` or `TRACE`, it enables the logging of information, such as headers and bodies sent and received across the wire. |
||||
To enable wiretap, set `spring.cloud.gateway.httpserver.wiretap=true` or `spring.cloud.gateway.httpclient.wiretap=true` for the `HttpServer` and `HttpClient`, respectively. |
||||
|
@ -0,0 +1,20 @@
@@ -0,0 +1,20 @@
|
||||
version: @antora-component.version@ |
||||
prerelease: @antora-component.prerelease@ |
||||
|
||||
asciidoc: |
||||
attributes: |
||||
attribute-missing: 'warn' |
||||
chomp: 'all' |
||||
project-root: @maven.multiModuleProjectDirectory@ |
||||
github-repo: @docs.main@ |
||||
github-raw: https://raw.githubusercontent.com/spring-cloud/@docs.main@/@github-tag@ |
||||
github-code: https://github.com/spring-cloud/@docs.main@/tree/@github-tag@ |
||||
github-issues: https://github.com/spring-cloud/@docs.main@/issues/ |
||||
github-wiki: https://github.com/spring-cloud/@docs.main@/wiki |
||||
spring-cloud-version: @project.version@ |
||||
github-tag: @github-tag@ |
||||
version-type: @version-type@ |
||||
docs-url: https://docs.spring.io/@docs.main@/docs/@project.version@ |
||||
raw-docs-url: https://raw.githubusercontent.com/spring-cloud/@docs.main@/@github-tag@ |
||||
project-version: @project.version@ |
||||
project-name: @docs.main@ |
@ -1,154 +0,0 @@
@@ -1,154 +0,0 @@
|
||||
|=== |
||||
|Name | Default | Description |
||||
|
||||
|spring.cloud.gateway.default-filters | | List of filter definitions that are applied to every route. |
||||
|spring.cloud.gateway.discovery.locator.enabled | `+++false+++` | Flag that enables DiscoveryClient gateway integration. |
||||
|spring.cloud.gateway.discovery.locator.filters | | |
||||
|spring.cloud.gateway.discovery.locator.include-expression | `+++true+++` | SpEL expression that will evaluate whether to include a service in gateway integration or not, defaults to: true. |
||||
|spring.cloud.gateway.discovery.locator.lower-case-service-id | `+++false+++` | Option to lower case serviceId in predicates and filters, defaults to false. Useful with eureka when it automatically uppercases serviceId. so MYSERIVCE, would match /myservice/** |
||||
|spring.cloud.gateway.discovery.locator.predicates | | |
||||
|spring.cloud.gateway.discovery.locator.route-id-prefix | | The prefix for the routeId, defaults to discoveryClient.getClass().getSimpleName() + "_". Service Id will be appended to create the routeId. |
||||
|spring.cloud.gateway.discovery.locator.url-expression | `+++'lb://'+serviceId+++` | SpEL expression that create the uri for each route, defaults to: 'lb://'+serviceId. |
||||
|spring.cloud.gateway.enabled | `+++true+++` | Enables gateway functionality. |
||||
|spring.cloud.gateway.fail-on-route-definition-error | `+++true+++` | Option to fail on route definition errors, defaults to true. Otherwise, a warning is logged. |
||||
|spring.cloud.gateway.filter.add-request-header.enabled | `+++true+++` | Enables the add-request-header filter. |
||||
|spring.cloud.gateway.filter.add-request-parameter.enabled | `+++true+++` | Enables the add-request-parameter filter. |
||||
|spring.cloud.gateway.filter.add-response-header.enabled | `+++true+++` | Enables the add-response-header filter. |
||||
|spring.cloud.gateway.filter.circuit-breaker.enabled | `+++true+++` | Enables the circuit-breaker filter. |
||||
|spring.cloud.gateway.filter.dedupe-response-header.enabled | `+++true+++` | Enables the dedupe-response-header filter. |
||||
|spring.cloud.gateway.filter.fallback-headers.enabled | `+++true+++` | Enables the fallback-headers filter. |
||||
|spring.cloud.gateway.filter.hystrix.enabled | `+++true+++` | Enables the hystrix filter. |
||||
|spring.cloud.gateway.filter.json-to-grpc.enabled | `+++true+++` | Enables the JSON to gRPC filter. |
||||
|spring.cloud.gateway.filter.local-response-cache.enabled | `+++false+++` | Enables the local-response-cache filter. |
||||
|spring.cloud.gateway.filter.local-response-cache.size | `+++5m+++` | Maximum size of the cache to evict entries for this route (in KB, MB and GB). |
||||
|spring.cloud.gateway.filter.local-response-cache.time-to-live | | Time to expire a cache entry (expressed in s for seconds, m for minutes, and h for hours). |
||||
|spring.cloud.gateway.filter.map-request-header.enabled | `+++true+++` | Enables the map-request-header filter. |
||||
|spring.cloud.gateway.filter.modify-request-body.enabled | `+++true+++` | Enables the modify-request-body filter. |
||||
|spring.cloud.gateway.filter.modify-response-body.enabled | `+++true+++` | Enables the modify-response-body filter. |
||||
|spring.cloud.gateway.filter.prefix-path.enabled | `+++true+++` | Enables the prefix-path filter. |
||||
|spring.cloud.gateway.filter.preserve-host-header.enabled | `+++true+++` | Enables the preserve-host-header filter. |
||||
|spring.cloud.gateway.filter.redirect-to.enabled | `+++true+++` | Enables the redirect-to filter. |
||||
|spring.cloud.gateway.filter.remove-hop-by-hop.headers | | |
||||
|spring.cloud.gateway.filter.remove-hop-by-hop.order | `+++0+++` | |
||||
|spring.cloud.gateway.filter.remove-request-header.enabled | `+++true+++` | Enables the remove-request-header filter. |
||||
|spring.cloud.gateway.filter.remove-request-parameter.enabled | `+++true+++` | Enables the remove-request-parameter filter. |
||||
|spring.cloud.gateway.filter.remove-response-header.enabled | `+++true+++` | Enables the remove-response-header filter. |
||||
|spring.cloud.gateway.filter.request-header-size.enabled | `+++true+++` | Enables the request-header-size filter. |
||||
|spring.cloud.gateway.filter.request-header-to-request-uri.enabled | `+++true+++` | Enables the request-header-to-request-uri filter. |
||||
|spring.cloud.gateway.filter.request-rate-limiter.default-key-resolver | | |
||||
|spring.cloud.gateway.filter.request-rate-limiter.default-rate-limiter | | |
||||
|spring.cloud.gateway.filter.request-rate-limiter.enabled | `+++true+++` | Enables the request-rate-limiter filter. |
||||
|spring.cloud.gateway.filter.request-size.enabled | `+++true+++` | Enables the request-size filter. |
||||
|spring.cloud.gateway.filter.retry.enabled | `+++true+++` | Enables the retry filter. |
||||
|spring.cloud.gateway.filter.rewrite-location-response-header.enabled | `+++true+++` | Enables the rewrite-location-response-header filter. |
||||
|spring.cloud.gateway.filter.rewrite-location.enabled | `+++true+++` | Enables the rewrite-location filter. |
||||
|spring.cloud.gateway.filter.rewrite-path.enabled | `+++true+++` | Enables the rewrite-path filter. |
||||
|spring.cloud.gateway.filter.rewrite-response-header.enabled | `+++true+++` | Enables the rewrite-response-header filter. |
||||
|spring.cloud.gateway.filter.save-session.enabled | `+++true+++` | Enables the save-session filter. |
||||
|spring.cloud.gateway.filter.secure-headers.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'+++` | |
||||
|spring.cloud.gateway.filter.secure-headers.content-type-options | `+++nosniff+++` | |
||||
|spring.cloud.gateway.filter.secure-headers.disable | | |
||||
|spring.cloud.gateway.filter.secure-headers.download-options | `+++noopen+++` | |
||||
|spring.cloud.gateway.filter.secure-headers.enabled | `+++true+++` | Enables the secure-headers filter. |
||||
|spring.cloud.gateway.filter.secure-headers.frame-options | `+++DENY+++` | |
||||
|spring.cloud.gateway.filter.secure-headers.permitted-cross-domain-policies | `+++none+++` | |
||||
|spring.cloud.gateway.filter.secure-headers.referrer-policy | `+++no-referrer+++` | |
||||
|spring.cloud.gateway.filter.secure-headers.strict-transport-security | `+++max-age=631138519+++` | |
||||
|spring.cloud.gateway.filter.secure-headers.xss-protection-header | `+++1 ; mode=block+++` | |
||||
|spring.cloud.gateway.filter.set-path.enabled | `+++true+++` | Enables the set-path filter. |
||||
|spring.cloud.gateway.filter.set-request-header.enabled | `+++true+++` | Enables the set-request-header filter. |
||||
|spring.cloud.gateway.filter.set-request-host-header.enabled | `+++true+++` | Enables the set-request-host-header filter. |
||||
|spring.cloud.gateway.filter.set-response-header.enabled | `+++true+++` | Enables the set-response-header filter. |
||||
|spring.cloud.gateway.filter.set-status.enabled | `+++true+++` | Enables the set-status filter. |
||||
|spring.cloud.gateway.filter.strip-prefix.enabled | `+++true+++` | Enables the strip-prefix filter. |
||||
|spring.cloud.gateway.forwarded.enabled | `+++true+++` | Enables the ForwardedHeadersFilter. |
||||
|spring.cloud.gateway.global-filter.adapt-cached-body.enabled | `+++true+++` | Enables the adapt-cached-body global filter. |
||||
|spring.cloud.gateway.global-filter.forward-path.enabled | `+++true+++` | Enables the forward-path global filter. |
||||
|spring.cloud.gateway.global-filter.forward-routing.enabled | `+++true+++` | Enables the forward-routing global filter. |
||||
|spring.cloud.gateway.global-filter.load-balancer-client.enabled | `+++true+++` | Enables the load-balancer-client global filter. |
||||
|spring.cloud.gateway.global-filter.local-response-cache.enabled | `+++true+++` | Enables the local-response-cache filter for all routes, it allows to add a specific configuration at route level using LocalResponseCache filter. |
||||
|spring.cloud.gateway.global-filter.netty-routing.enabled | `+++true+++` | Enables the netty-routing global filter. |
||||
|spring.cloud.gateway.global-filter.netty-write-response.enabled | `+++true+++` | Enables the netty-write-response global filter. |
||||
|spring.cloud.gateway.global-filter.reactive-load-balancer-client.enabled | `+++true+++` | Enables the reactive-load-balancer-client global filter. |
||||
|spring.cloud.gateway.global-filter.remove-cached-body.enabled | `+++true+++` | Enables the remove-cached-body global filter. |
||||
|spring.cloud.gateway.global-filter.route-to-request-url.enabled | `+++true+++` | Enables the route-to-request-url global filter. |
||||
|spring.cloud.gateway.global-filter.websocket-routing.enabled | `+++true+++` | Enables the websocket-routing global filter. |
||||
|spring.cloud.gateway.globalcors.add-to-simple-url-handler-mapping | `+++false+++` | If global CORS config should be added to the URL handler. |
||||
|spring.cloud.gateway.globalcors.cors-configurations | | |
||||
|spring.cloud.gateway.handler-mapping.order | `+++1+++` | The order of RoutePredicateHandlerMapping. |
||||
|spring.cloud.gateway.httpclient.compression | `+++false+++` | Enables compression for Netty HttpClient. |
||||
|spring.cloud.gateway.httpclient.connect-timeout | | The connect timeout in millis, the default is 30s. |
||||
|spring.cloud.gateway.httpclient.max-header-size | | The max response header size. |
||||
|spring.cloud.gateway.httpclient.max-initial-line-length | | The max initial line length. |
||||
|spring.cloud.gateway.httpclient.pool.acquire-timeout | | Only for type FIXED, the maximum time in millis to wait for acquiring. |
||||
|spring.cloud.gateway.httpclient.pool.eviction-interval | `+++0+++` | Perform regular eviction checks in the background at a specified interval. Disabled by default ({@link Duration#ZERO}) |
||||
|spring.cloud.gateway.httpclient.pool.max-connections | | Only for type FIXED, the maximum number of connections before starting pending acquisition on existing ones. |
||||
|spring.cloud.gateway.httpclient.pool.max-idle-time | | Time in millis after which the channel will be closed. If NULL, there is no max idle time. |
||||
|spring.cloud.gateway.httpclient.pool.max-life-time | | Duration after which the channel will be closed. If NULL, there is no max life time. |
||||
|spring.cloud.gateway.httpclient.pool.metrics | `+++false+++` | Enables channel pools metrics to be collected and registered in Micrometer. Disabled by default. |
||||
|spring.cloud.gateway.httpclient.pool.name | `+++proxy+++` | The channel pool map name, defaults to proxy. |
||||
|spring.cloud.gateway.httpclient.pool.type | | Type of pool for HttpClient to use, defaults to ELASTIC. |
||||
|spring.cloud.gateway.httpclient.proxy.host | | Hostname for proxy configuration of Netty HttpClient. |
||||
|spring.cloud.gateway.httpclient.proxy.non-proxy-hosts-pattern | | Regular expression (Java) for a configured list of hosts. that should be reached directly, bypassing the proxy |
||||
|spring.cloud.gateway.httpclient.proxy.password | | Password for proxy configuration of Netty HttpClient. |
||||
|spring.cloud.gateway.httpclient.proxy.port | | Port for proxy configuration of Netty HttpClient. |
||||
|spring.cloud.gateway.httpclient.proxy.type | | proxyType for proxy configuration of Netty HttpClient. |
||||
|spring.cloud.gateway.httpclient.proxy.username | | Username for proxy configuration of Netty HttpClient. |
||||
|spring.cloud.gateway.httpclient.response-timeout | | The response timeout. |
||||
|spring.cloud.gateway.httpclient.ssl.close-notify-flush-timeout | `+++3000ms+++` | SSL close_notify flush timeout. Default to 3000 ms. |
||||
|spring.cloud.gateway.httpclient.ssl.close-notify-read-timeout | `+++0+++` | SSL close_notify read timeout. Default to 0 ms. |
||||
|spring.cloud.gateway.httpclient.ssl.handshake-timeout | `+++10000ms+++` | SSL handshake timeout. Default to 10000 ms |
||||
|spring.cloud.gateway.httpclient.ssl.key-password | | Key password, default is same as keyStorePassword. |
||||
|spring.cloud.gateway.httpclient.ssl.key-store | | Keystore path for Netty HttpClient. |
||||
|spring.cloud.gateway.httpclient.ssl.key-store-password | | Keystore password. |
||||
|spring.cloud.gateway.httpclient.ssl.key-store-provider | | Keystore provider for Netty HttpClient, optional field. |
||||
|spring.cloud.gateway.httpclient.ssl.key-store-type | `+++JKS+++` | Keystore type for Netty HttpClient, default is JKS. |
||||
|spring.cloud.gateway.httpclient.ssl.trusted-x509-certificates | | Trusted certificates for verifying the remote endpoint's certificate. |
||||
|spring.cloud.gateway.httpclient.ssl.use-insecure-trust-manager | `+++false+++` | Installs the netty InsecureTrustManagerFactory. This is insecure and not suitable for production. |
||||
|spring.cloud.gateway.httpclient.websocket.max-frame-payload-length | | Max frame payload length. |
||||
|spring.cloud.gateway.httpclient.websocket.proxy-ping | `+++true+++` | Proxy ping frames to downstream services, defaults to true. |
||||
|spring.cloud.gateway.httpclient.wiretap | `+++false+++` | Enables wiretap debugging for Netty HttpClient. |
||||
|spring.cloud.gateway.httpserver.wiretap | `+++false+++` | Enables wiretap debugging for Netty HttpServer. |
||||
|spring.cloud.gateway.loadbalancer.use404 | `+++false+++` | |
||||
|spring.cloud.gateway.metrics.enabled | `+++false+++` | Enables the collection of metrics data. |
||||
|spring.cloud.gateway.metrics.prefix | `+++spring.cloud.gateway+++` | The prefix of all metrics emitted by gateway. |
||||
|spring.cloud.gateway.metrics.tags | | Tags map that added to metrics. |
||||
|spring.cloud.gateway.observability.enabled | `+++true+++` | If Micrometer Observability support should be turned on. |
||||
|spring.cloud.gateway.predicate.after.enabled | `+++true+++` | Enables the after predicate. |
||||
|spring.cloud.gateway.predicate.before.enabled | `+++true+++` | Enables the before predicate. |
||||
|spring.cloud.gateway.predicate.between.enabled | `+++true+++` | Enables the between predicate. |
||||
|spring.cloud.gateway.predicate.cloud-foundry-route-service.enabled | `+++true+++` | Enables the cloud-foundry-route-service predicate. |
||||
|spring.cloud.gateway.predicate.cookie.enabled | `+++true+++` | Enables the cookie predicate. |
||||
|spring.cloud.gateway.predicate.header.enabled | `+++true+++` | Enables the header predicate. |
||||
|spring.cloud.gateway.predicate.host.enabled | `+++true+++` | Enables the host predicate. |
||||
|spring.cloud.gateway.predicate.method.enabled | `+++true+++` | Enables the method predicate. |
||||
|spring.cloud.gateway.predicate.path.enabled | `+++true+++` | Enables the path predicate. |
||||
|spring.cloud.gateway.predicate.query.enabled | `+++true+++` | Enables the query predicate. |
||||
|spring.cloud.gateway.predicate.read-body.enabled | `+++true+++` | Enables the read-body predicate. |
||||
|spring.cloud.gateway.predicate.remote-addr.enabled | `+++true+++` | Enables the remote-addr predicate. |
||||
|spring.cloud.gateway.predicate.weight.enabled | `+++true+++` | Enables the weight predicate. |
||||
|spring.cloud.gateway.predicate.xforwarded-remote-addr.enabled | `+++true+++` | Enables the xforwarded-remote-addr predicate. |
||||
|spring.cloud.gateway.redis-rate-limiter.burst-capacity-header | `+++X-RateLimit-Burst-Capacity+++` | The name of the header that returns the burst capacity configuration. |
||||
|spring.cloud.gateway.redis-rate-limiter.config | | |
||||
|spring.cloud.gateway.redis-rate-limiter.include-headers | `+++true+++` | Whether or not to include headers containing rate limiter information, defaults to true. |
||||
|spring.cloud.gateway.redis-rate-limiter.remaining-header | `+++X-RateLimit-Remaining+++` | The name of the header that returns number of remaining requests during the current second. |
||||
|spring.cloud.gateway.redis-rate-limiter.replenish-rate-header | `+++X-RateLimit-Replenish-Rate+++` | The name of the header that returns the replenish rate configuration. |
||||
|spring.cloud.gateway.redis-rate-limiter.requested-tokens-header | `+++X-RateLimit-Requested-Tokens+++` | The name of the header that returns the requested tokens configuration. |
||||
|spring.cloud.gateway.restrictive-property-accessor.enabled | `+++true+++` | Restricts method and property access in SpEL. |
||||
|spring.cloud.gateway.routes | | List of Routes. |
||||
|spring.cloud.gateway.set-status.original-status-header-name | | The name of the header which contains http code of the proxied request. |
||||
|spring.cloud.gateway.streaming-media-types | | |
||||
|spring.cloud.gateway.x-forwarded.enabled | `+++true+++` | If the XForwardedHeadersFilter is enabled. |
||||
|spring.cloud.gateway.x-forwarded.for-append | `+++true+++` | If appending X-Forwarded-For as a list is enabled. |
||||
|spring.cloud.gateway.x-forwarded.for-enabled | `+++true+++` | If X-Forwarded-For is enabled. |
||||
|spring.cloud.gateway.x-forwarded.host-append | `+++true+++` | If appending X-Forwarded-Host as a list is enabled. |
||||
|spring.cloud.gateway.x-forwarded.host-enabled | `+++true+++` | If X-Forwarded-Host is enabled. |
||||
|spring.cloud.gateway.x-forwarded.order | `+++0+++` | The order of the XForwardedHeadersFilter. |
||||
|spring.cloud.gateway.x-forwarded.port-append | `+++true+++` | If appending X-Forwarded-Port as a list is enabled. |
||||
|spring.cloud.gateway.x-forwarded.port-enabled | `+++true+++` | If X-Forwarded-Port is enabled. |
||||
|spring.cloud.gateway.x-forwarded.prefix-append | `+++true+++` | If appending X-Forwarded-Prefix as a list is enabled. |
||||
|spring.cloud.gateway.x-forwarded.prefix-enabled | `+++true+++` | If X-Forwarded-Prefix is enabled. |
||||
|spring.cloud.gateway.x-forwarded.proto-append | `+++true+++` | If appending X-Forwarded-Proto as a list is enabled. |
||||
|spring.cloud.gateway.x-forwarded.proto-enabled | `+++true+++` | If X-Forwarded-Proto is enabled. |
||||
|
||||
|=== |
@ -1,20 +0,0 @@
@@ -1,20 +0,0 @@
|
||||
:numbered!: |
||||
[appendix] |
||||
[[common-application-properties]] |
||||
== Common application properties |
||||
|
||||
include::_attributes.adoc[] |
||||
|
||||
Various properties can be specified inside your `application.properties` file, inside your `application.yml` file, or as command line switches. |
||||
This appendix provides a list of common {project-full-name} properties and references to the underlying classes that consume them. |
||||
|
||||
NOTE: Property contributions can come from additional jar files on your classpath, so you should not consider this an exhaustive list. |
||||
Also, you can define your own properties. |
||||
|
||||
include::_configprops.adoc[] |
||||
|
||||
include::{project-root}/docs/target/observability/_metrics.adoc[] |
||||
|
||||
include::{project-root}/docs/target/observability/_spans.adoc[] |
||||
|
||||
include::{project-root}/docs/target/observability/_conventions.adoc[] |
@ -1 +0,0 @@
@@ -1 +0,0 @@
|
||||
include::spring-cloud-gateway.adoc[] |
Loading…
Reference in new issue