Spring Cloud Gateway
What is Gateway?
A Gateway is a central entry point that sits between clients(users/apps) and backend services, acting as a traffic controller and security guard for requests Client → Gateway → Backend Services
- Request routing
- Security and access controller
- Traffic management
- Request and response transformation
- Monitoring & logging Common Gateway
- Spring cloud gateway(this article)
- Kong
- NGINX
- AWS API Gateway
Gateway in microservices architecture
The gateway is almost mandatory because it:
- Hides internal services
- Protects the system
- Simplifes client communication
Spring Cloud Gateway Server WebFlux
Glossary
- 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 Java 8 Function Predicate. The input type is a Spring Framework ServerWebExchange. This lets you match on anything from the HTTP request, such as headers or parameters.
- Filter: These are instances of GatewayFilter that have been constructed with a specific factory. Here, you can modify requests and responses before or after sending the downstream request.
How It Works
The following diagram provides a high-level overview of how Spring Cloud Gateway works:
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(Coordinate the filter chain). 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.
Configuring Route Predicate Factories and Gateway Filter Factories
Configuring Route Predicate Factories and Gateway Filter Factories
- Shortcut Configuration
- Fully Expanded Arguments
Route Predicate Factories: The Predicate decides whether this request CAN enter the route or not (Route Predicate Factories are defined).
Gateway Filter Factories: Filters decide "what to do" with the request/response AFTER the route has been selected (Gateway Filter Factories are defined).
Shortcut Configuration
Shortcut configuration is recognized by the filter name, followed by an equals sign (=), followed by argument values separated by commas (,). application.yml
spring:
cloud:
gateway:
routes:
- id: after_route
uri: https://example.org
predicates:
- Cookie=mycookie,mycookievalue
Explanation
- Cookie is a Route Predicate Factory
- mycookie is the cookie name
- mycookievalue is the expected value
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.
spring:
cloud:
gateway:
routes:
- id: after_route
uri: https://example.org
predicates:
- name: Cookie
args:
name: mycookie
regexp: mycookievalue
Explanation
- Cookie is a Route Predicate Factory
- mycookie is the cookie name
- mycookievalue is the expected value
Global Filters
Global Filters
- Combined Global Filter and GatewayFilter Ordering
- The Gateway Metrics Filter
- The Local Response Cache Filter
- Forward Routing Filter
- The Netty Routing Filter
- The Netty Write Response Filter
- ReactiveLoadBalancerClientFilter
- RouteToRequestUrl Filter
- The Websocket Routing Filter
- Marking An Exchange As Routed
Combined Global Filter and GatewayFilter Ordering
- Collect all GlobalFilters
- Collect all GatewayFilters for that route
- Combine them into a single filter chain
- Order the filter chain in the order org.springframework.core.Ordered
The following listing configures a filter chain:
@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 is the default filter in Spring Cloud Gateway used for:
Thu thập số liệu (metrics) cho từng request đi qua Gateway
Các số liệu này phục vụ:
- Giám sát hệ thống
- Theo dõi hiệu năng API
- Vẽ dashboard Grafana
- Cảnh báo (alert) khi lỗi / chậm
You need to add the dependency:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
After adding it, Gateway Metrics Filter will automatically run by default, as long as the following configuration is not set to false.
spring:
cloud:
gateway:
metrics:
enabled: true # default is true
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 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.
Thanks to these tags you can:
- Identify which routes have the most errors
- Identify which APIs are slow
- Identify which backends frequently return 5xx
The Local Response Cache Filter
LocalResponseCache is a Gateway Filter that caches responses directly in Spring Cloud Gateway, so there is no need for Redis or a distributed cache. It uses Caffeine, a very fast in-memory cache that runs locally in the Gateway’s JVM. Goals:
- Reduce the number of requests sent to the backend
- Improve response time for GET APIs
- Suitable for data that chanes infrequently
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
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 no cache parameters are configured but the global filter is enabled, Spring Cloud Gateway uses a default cache time-to-live (TTL) of 5 minutes for responses.
The filter automatically manages the Cache-Control: max-age header.
If the original response already contains max-age, it is overwritten with the value defined by timeToLive.
For later requests, max-age is recalculated to reflect the remaining time before the cache expires.
Setting spring.cloud.gateway.global-filter.local-response-cache.enabled=false disables response caching for all routes.
Forward Routing Filter, The Netty Routing Filter, The Netty Write Response Filter, ReactiveLoadBalancerClientFilter, RouteToRequestUrl Filter, The Websocket Routing Filter, Marking An Exchange As Routed (content)
HttpHeadersFilters
HttpHeadersFilters *Forwarded Headers Filter *RemoveHopByHop Headers Filter *XForwarded 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. To activate this filter set the spring.cloud.gateway.server.webflux.trusted-proxies property to a Java Regular Expression. This regular expression defines the proxies that are trusted when they appear in the Forwarded header.
spring.cloud.gateway.server.webflux.trusted-proxies=10\\.0\\.0\\.5
The Forwarded by header part can be enabled by setting the following property to true (defaults to false): spring.cloud.gateway.server.webflux.forwarded.by.enabled=true
RemoveHopByHop Headers Filter
The RemoveHopByHop Headers Filter removes headers from forwarded requests. The default list of headers that is removed comes from the 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.server.webflux.filter.remove-hop-by-hop.headers property to the list of header names to remove.
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. To activate this filter set the spring.cloud.gateway.server.webflux.trusted-proxies property to a Java Regular Expression. This regular expression defines the proxies that are trusted when they appear in the Forwarded header. Creating of individual headers can be controlled by the following boolean properties (defaults to true):
- spring.cloud.gateway.server.webflux.x-forwarded.for-enabled
- spring.cloud.gateway.server.webflux.x-forwarded.host-enabled
- spring.cloud.gateway.server.webflux.x-forwarded.port-enabled
- spring.cloud.gateway.server.webflux.x-forwarded.proto-enabled
- spring.cloud.gateway.server.webflux.x-forwarded.prefix-enabled Appending multiple headers can be controlled by the following boolean properties (defaults to true):
- spring.cloud.gateway.server.webflux.x-forwarded.for-append
- spring.cloud.gateway.server.webflux.x-forwarded.host-append
- spring.cloud.gateway.server.webflux.x-forwarded.port-append
- spring.cloud.gateway.server.webflux.x-forwarded.proto-append
- spring.cloud.gateway.server.webflux.x-forwarded.prefix-append
CORS Configuration
Global CORS Configuration
CORS The “global” CORS configuration is a map of URL patterns to Spring Framework CorsConfiguration. The following example configures CORS
spring:
cloud:
gateway:
globalcors:
cors-configurations:
'[/**]':
allowedOrigins: "https://docs.spring.io"
allowedMethods:
- GET
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
The “route” configuration allows applying CORS directly to a route as metadata with key cors.
spring:
cloud:
gateway:
routes:
- id: cors_route
uri: https://example.org
predicates:
- Path=/service/**
metadata:
cors:
allowedOrigins: '*'
allowedMethods:
- GET
- POST
allowedHeaders: '*'
maxAge: 30
All rights reserved