An API Gateway provides a single entry point for all the microservices running downstream. There are many gateway solutions available such as Zuul, Linkerd, Nginx, etc. but in this article, we will specifically discuss Spring Cloud Gateway - a reactive Gateway built upon Project Reactor, Spring WebFlux, and Spring Boot 2.0.
Zuul Vs Spring Cloud Gateway
Spring Cloud Gateway is a non-blocking gateway while Zuul1 is a blocking gateway. In case of non-blocking, the main thread is always available to serve the request and other multiple threads process those requests asynchronously in the background and once the request is completely processed the response is returned. Hence non-blocking model requires a less no of resources to serve the same amount of requests as compared to blocking gateway.
Though Zuul2 is also a non-blocking gateway but Spring Cloud does not provide integration with Zuul2 out of the box and there are many features in spring cloud gateway that is not available in Zuul2 for publicly such as request limiting.
Spring Cloud Gateway Architecture
Once a request reaches to the gateway, the first thing gateway does is to match the request with each of the available route based on the predicate defined. Once, the route has matched the request moves to web handler and the filters will be applied to the request. There are many out of the box filters provided by the gateway itself to modify the request header as well as the body. Pre-filters are applied specifically to a route whereas global filters can be applied to all the route request. Global filters can be applied to perform authentication and authorization of all the request at one place.
Route Definition in Spring Cloud Gateway
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.
Below is an example of a route that has a predicate defined to match all the request URL with /api/v1/queue/** and apply a pre-filter to rewrite the path. There is another filter applied to modify the request header and then route the request to load balanced FIRST-SERVICE.
builder.routes()
.route(r -> r.path("/api/v1/first/**")
.filters(f -> f.rewritePath("/api/v1/first/(?.*)", "/${remains}")
.addRequestHeader("X-first-Header", "first-service-header")
)
.uri("lb://FIRST-SERVICE/") //downstream endpoint lb - load balanced
.id("queue-service"))
.build();
Below is the equivalent .yaml configuration.
spring:
cloud:
gateway:
routes:
- id: first-service
uri: lb://FIRST-SERVICE
predicates:
- Path=/api/v1/first/**
filters:
- RewritePath=/api/v1/first/(?.*), /$\{remains}
- AddRequestHeader=X-first-Header, first-service-header
WebSocket Connection in Spring Cloud gateway
The ability to have real-time two-way communication between the client and the server is a key feature in most modern web apps. As we know, Zuul 1 does not support WebSocket connection whereas Spring Cloud Gateway provides excellent and easily configurable support for WebSockets.
Below is a route definition for load-balanced WebSockets. For notification-service, we have a route configured as any request matching with the path /websocket will be routed to notification-service.
.route(r -> r.path("/websocket/**")
.filters(f -> f.rewritePath("/websocket/(?.*)", "/${remains}"))
.uri("lb://NOTIFICATION-SERVICE/")
.id("notification-service"))
There are tons of features provided by Spring Cloud Gateway out of the box. You can get started with this example on Spring Cloud Gateway to know all the features of Spring Cloud Gateway.
Top comments (0)