Spring Cloud Gateway
1. Overview
In this article, we’ll explore the main features of the Spring Cloud Gateway project, a new API based on Spring 5, Spring Boot 2 and Project Reactor.
The tool provides out-of-the-box routing mechanisms often used in microservices applications as a way of hiding multiple services behind a single facade.
2. Routing Handler
Being focused on routing requests, the Spring Cloud Gateway forwards requests to a Gateway Handler Mapping – which determines what should be done with requests matching a specific route.
Let’s start with a quick example of how to the Gateway Handler resolves route configurations by using RouteLocator:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| @Bean public RouteLocator routingConfig() { return Routes.locator() .route( "baeldung" ) .uri( "http://baeldung.com" ) .predicate(host( "**.baeldung.com" )) .and() .route( "myOtherRouting" ) .id( "myOtherID" ) .uri( "http://othersite.com" ) .predicate(get( "**.baeldung.com" )) .and() .build(); } |
Notice how we made use of the main building blocks of this API:
- Route – the primary API of the gateway. It is defined by a given identification (ID), a destination (URI) and set of predicates and filters
- Predicate – a Java 8’s Predicate – which is used for matching HTTP requests using headers, methods or parameters
- Filter – a standard Spring’s WebFilter
3. Dynamic Routing
Just like Zuul, Spring Cloud Gateway provides means for routing requests to different services.
The routing configuration can be created by using pure Java (RouteLocator, as shown in the example in section 2.1) or by using properties configuration:
1
2
3
4
5
6
7
8
9
10
| spring: application: name: gateway-service cloud: gateway: routes: - id: baeldung uri: baeldung.com - id: myOtherRouting uri: localhost:9999 |
4. Routing Factories
Spring Cloud Gateway matches routes using the Spring WebFlux HandlerMapping infrastructure.
It also includes many built-in Route Predicate Factories. All of these predicates match different attributes of the HTTP request. Multiple Route Predicate Factories can be combined via the logical “and”.
Route matching can be applied both programmatically or via configuration properties file using a different type of Route Predicate Factories.
4.1. Before Route Predicate Factory
The Before Route Predicate Factory takes one parameter: a datetime. This predicate matches requests that happen before the current datetime:
1
2
3
4
5
6
7
8
| spring: cloud: gateway: routes: - id: before_route uri: http: //baeldung.com predicates: - Before=2017-09-11T17:42:47.789-07:00[America/Alaska] |
The Java configuration can be represented as:
1
2
3
4
| //..route definition .id( "before_route" ) .uri( "http://baeldung.com" ) .predicate(before(LocalDateTime.now().atZone(ZoneId.systemDefault())) |
4.2. Between Route Predicate Factory
The Between Route Predicate Factory takes two parameters: datetime1, and datetime2. This predicate matches requests that happen after datetime1(inclusive) and before datetime2 (exclusive). The datetime2 parameter must be after datetime1:
1
2
3
4
5
6
7
8
| spring: cloud: gateway: routes: - id: between_route uri: http: //baeldung.com predicates: - Between=2017-09-10T17:42:47.789-07:00[America/Alaska], 2017-09-11T17:42:47.789-07:00[America/Alaska] |
And the Java configuration looks like this:
1
2
3
4
5
6
| ZonedDateTime datetime1 = LocalDateTime.now().minusDays( 1 ).atZone(ZoneId.systemDefault()); ZonedDateTime datetime2 = LocalDateTime.now().atZone(ZoneId.systemDefault()) //..route definition .id( "between_route" ) .uri( "http://baeldung.com" ) .predicate(between(datetime1, datetime2)) |
4.3. Header Route Predicate Factory
The Header Route Predicate Factory takes two parameters: the header name, and a regular expression. This predicate matches a header matching the regular expression:
1
2
3
4
5
6
7
8
| spring: cloud: gateway: routes: - id: header_route uri: http: //baeldung.com predicates: - Header=X-Request-Id, \d+ |
The Java configuration can be represented as:
1
2
3
4
| //..route definition .id( "header_route" ) .uri( "http://baeldung.com" ) .predicate(header( "X-Request-Id" , "\d+" )) |
4.4. Host Route Predicate Factor
The Host Route Predicate Factory takes one parameter: the hostname pattern. The pattern is an Ant-style pattern with “.” as the separator.
This predicate matches the Host header with the given the pattern:
1
2
3
4
5
6
7
8
| spring: cloud: gateway: routes: - id: host_route uri: http: //baeldung.com predicates: - Host=**.baeldung.com |
Here’s the Java configuration alternative:
1
2
3
4
| //..route definition .id( "host_route" ) .uri( "http://baeldung.com" ) .predicate(host( "**.baeldung.com" )) |
4.5. Method Route Predicate Factory
The Method Route Predicate Factory takes one parameter: the HTTP method to match:
1
2
3
4
5
6
7
8
| spring: cloud: gateway: routes: - id: method_route uri: http: //baeldung.com predicates: - Method=GET |
The Java configuration can be represented as:
1
2
3
4
|
4.6. Path Route Predicate Factory
The Path Route Predicate Factory takes one parameter: a Spring PathMatcherpattern:
1
2
3
4
5
6
7
8
| spring: cloud: gateway: routes: - id: path_route uri: http: //baeldung.com predicates: - Path=/articles/{articleId} |
The Java configuration:
1
2
3
4
| //..route definition .id( "path_route" ) .uri( "http://baeldung.com" ) .predicate(path( "/articles/" +articleId)) |
4.7. Query Route Predicate Factory
The Query Route Predicate Factory takes two parameters: a required param and an optional regexp:
1
2
3
4
5
6
7
8
| spring: cloud: gateway: routes: - id: query_route uri: http: //baeldung.com predicates: - Query=articleId, \w |
And the Java configuration:
1
2
3
4
| //..route definition .id( "query_route" ) .uri( "http://baeldung.com" ) .predicate(query( "articleId" , "\w" )) |
4.8. RemoteAddr Route Predicate Factory
The RemoteAddr Route Predicate Factory takes a list (minimum of 1) of CIDR-notation strings, e.g., 192.168.0.1/16 (where 192.168.0.1 is an IP address, and 16 is a subnet mask):
1
2
3
4
5
6
7
8
| spring: cloud: gateway: routes: - id: remoteaddr_route uri: http: //baeldung.com predicates: - RemoteAddr=192.168.1.1/24 |
And the corresponding Java configuration:
1
2
3
4
| //..route definition .id( "remoteaddr_route" ) .uri( "http://baeldung.com" ) .predicate(remoteAddr( "192.168.1.1/24" ))
5. WebFilter Factories
Route filters make the modification of the incoming HTTP request or outgoing HTTP response possible.
Spring Cloud Gateway includes many built-in WebFilter Factories.
5.1. AddRequestHeader WebFilter Factory
The AddRequestHeader WebFilter Factory takes a name and value parameter:
Here’s the corresponding Java config:
5.2. AddRequestParameter WebFilter Factory
The AddRequestParameter WebFilter Factory takes a name and value parameter:
The corresponding Java configuration:
5.3. AddResponseHeader WebFilter Factory
The AddResponseHeader WebFilter Factory takes a name and value parameter:
The corresponding Java configuration:
5.4. Circuit Breaker WebFilter Factory
Hystrix is used as Circuit-Breaker WebFilter Factory and takes a single name parameter, which is the name of the Hystrix command:
The corresponding Java configuration:
5.5. RedirectTo WebFilter Factory
The RedirectTo WebFilter Factory takes a status and a URL parameter. The status should be a 300 redirect HTTP code, such as 301:
And the corresponding Java configuration:
5.6. RewritePath WebFilter Factory
The RewritePath WebFilter Factory takes a path regexp parameter and a replacement parameter. This uses Java regular expressions to rewrite the request path.
Here is a configuration example:
The Java configuration can be represented as:
5.7. RequestRateLimiter WebFilter Factory
The RequestRateLimiter WebFilter Factory takes three parameters: replenishRate, capacity, and keyResolverName.
The KeyResolver interface allows pluggable strategies to derive the key for limiting requests:
The Java configuration can be represented as:
Reference:
|
Comments
Post a Comment