An API Gateway acts as a reverse proxy sitting between client and micro services, routing requests from client side to various micro-services . User/client makes a request to a single host (gateway server) and need not know all the microservices servers , just single entry point to your application .
Why API Gateway ?
- Layer 7 routing and load balancing => enables the load balancer to make smarter load‑balancing decisions, and to apply optimizations and changes to the content (such as compression and encryption). That means based on the content of the request , the routing can be done to specific servers which stores that particular content . Check the example here.
- Modify Requests & Reponse => incoming requests can be modified based a logic using filters , similarly outgoing reponse can be modified at gateway layer before going out .
- Handling cross-cutting concerns => Authentication& authorization (Centralized Security), SSL termination, logging can be handled at the gateway server which reduces significant development on the end microservices side.
Spring Cloud Gateway & Reactive Programming
We will be using Spring cloud gateway (SCG) which is built on top of
> Spring Framework 5
> Project Reactor and
> Spring Boot 2.0 .
SCG supports non-blocking APIs , asynchronous request processing, as opposed to blocking apis which work on a thread per request model. Async (non-blocking) systems operate differently, with generally one thread handling large number of requests and responses.
- When a request comes , a servlet thread is assigned to it and instead of waiting for each request to complete processing , thread asks for the callback → “when the processing is done , call me back“ and moves on to serve other incoming requests . There is no blocking of thread in case the service has any operation that is time consuming like db operation or other processing . When that processing or db operation is completed , thread is notified that data is ready to be sent back and the response is returned back to the client .
A very good explaination is given on Defog Tech YT video here .
The lifecycle of the request and response is handled through events and callbacks . Hence lesser number of threads would be required as single thread will be able to serve multiple incoming requests and thread will not be blocked sitting idle with each request.
Zuul Gateway— Blocking
Zuul2 and Spring Cloud Gateway — Non-blocking
Now lets get to code using Spring Cloud Gateway with Springboot
Note — We have a random application already running at 9091 port . We will aim to add a gateway and route our requests to that application .
1 . Create a simple Springboot app from Spring Initilizr and add these important dependencies for gateway application pom.xml :
We can provide the routing configuration with Spring Cloud Gateway either in properties file or in Java . We will be using yml file to configure :
2. create application.yml
- id: order-route
The configuration is pretty intuitive , lets break it down , as gateways’ main purpose is routing , you can see that as a major block of the config “routes”.
“-id” — is a unique identifier for this route. (you can name the route anything)
“uri” — is the microservice / target host and port here the incoming request needs to be routed to .
“predicates” — It is a condition that when the request follows , the routing is performed to the micro-service running at the uri host server.
3. Let’s run this application and hit the gateway api and it should redirect to the service running at port 9091 .
Currently the application running at 9091 gives the following response :
So , now if we hit the gateway api , we should be redirected to this service .Let’s hit the same request with gateway host and port . My gateway app is running at 8085 as you can see in the config .
We can see , the request sent to gateway app has been routed to service running at localhost 9091 .
=> Apart from path predicate , there are several other predicates that are available in SCG like hostname pattern , before route (route requests coming before certain timestamp), after route(route requests coming after certain timestamp) etc. All predicates can be clubbed in the below fashion :
- id: order-route
So as long as the request is made before Jan-20–2022 , it will successfully route to application running at localhost 9091 .
Now Let’s try to modify the outgoing response using filters : -
name: gateway cloud:
- id: order-service
- AddResponseHeader=X-Request-color, blue
Here , we have added a filter i.e AddResponseHeader (one of many filter factories available) , that will add the header “X-Request-color” with value “blue” in the response , and obviously the predicate condition is respected . So, for all the incoming requests having path “/orders” will be routed to “http://localhost:9091/” and their response will have an additional header (X-Request-color -> blue) .
Let’s hit the gateway api on postman and test it :
As you can see , we have an additional header in the response for the request that followed the predicate condition .
A very good and easily understandable example is shown here in SpringDeveloper channel in YT that contains Java style of adding the routes in the gateway application .
To summarise , this was a basic example of what is API gateway , why and how Spring Cloud gateway to be used for better performance and reactive micro-service architecture .
Spring Cloud Gateway
Spring Cloud Gateway provides a utility object called ProxyExchange. You can use it inside a regular Spring web handler…
Spring Cloud Gateway Tutorial
Before we dive in to nitty gritty details of spring cloud gateway, let’s touch up on some basics around reverse proxy…
Spring Cloud: Routing with Zuul and Gateway
Overview In this article, we'll introduce you to routing your applications via Netflix's Zuul…