1. Imagine You Are Visiting a Big Shopping Mall ๐๏ธ
Hey buddy! Imagine you are visiting a big shopping mall.
Inside the mall, there are many shops:
- A clothing shop
- A food shop
- A mobile shop
- A shoe shop
Now imagine you want to buy clothes.
Do you need to enter through a different entrance for every shop?
No! You enter through the main entrance and then go to the shop you need.
The main entrance makes it easy to access all the shops.
In microservices, an API Gateway works like the main entrance of a shopping mall.
It provides a single entry point through which clients can access multiple microservices.
Let’s understand this with a simple diagram.
Client
|
v
API Gateway
|
+--------+--------+
| | |
v v v
Product Order Payment
Service Service Service
The client sends a request to the API Gateway.
The gateway decides which microservice should receive that request and forwards it to the appropriate destination.
This is the basic idea behind API Gateway.
2. What Is an API Gateway?
An API Gateway is a component that acts as the entry point between clients and backend microservices.
Instead of allowing clients to communicate directly with every microservice, we can route their requests through the gateway.
For example, imagine an e-commerce application with three microservices:
- Product Service โ manages product information.
- Order Service โ manages orders.
- Payment Service โ manages payments.
Without an API Gateway, the client may need to know the address of every service.
Client ------> Product Service
Client ------> Order Service
Client ------> Payment Service
Now imagine we change the address of Order Service or split it into multiple services.
The clients may need to update their routing logic.
This creates additional maintenance work.
With an API Gateway:
Client
|
v
API Gateway
|
+------> Product Service
|
+------> Order Service
|
+------> Payment Service
The client communicates through the gateway, and the gateway handles routing.
If the internal service structure changes, we can often update the gateway’s routing configuration instead of changing every client.
This is one of the main advantages of API Gateway.
3. What Are the Benefits of API Gateway?
Your application can use an API Gateway for several purposes.
1. Routing
The gateway forwards requests to the correct microservice.
For example:
/products/101 โ Product Service
/orders/101 โ Order Service
2. Load balancing
If multiple instances of Product Service are running, the gateway can distribute requests among available instances using Spring Cloud LoadBalancer.
3. Authentication
The gateway can validate authentication credentials, such as JWT tokens, before forwarding requests.
4. Rate limiting
It can limit how many requests a client is allowed to make during a specified period.
5. Resilience
It can integrate with Retry and Circuit Breaker mechanisms to handle certain downstream failures.
6. Request and response transformation
The gateway can add or remove HTTP headers and perform other supported request or response modifications.
7. Monitoring and logging
It can provide a central place to collect request information, logs, and metrics.
The exact capabilities depend on the gateway implementation and how it is configured.
4. Let’s Build an API Gateway Using Spring Boot
Now let’s implement a simple example using Spring Cloud Gateway.
We will create three applications:
<box border radius=”lg” padding={3} gap={3}> <row align=”center” gap={3}> <box background=”#DCEAFE” radius=”md” size=”48px” align=”center” justify=”center”> <icon name=”package” size=”xl” color=”#174EA6″/> </box> <box flex=”1″ gap={1}> **Product Service** <text color=”secondary” size=”sm”>Port: 8082 ยท Returns product information</text> </box> </row> <divider color=”subtle”/> <row align=”center” gap={3}> <box background=”#DDF7E5″ radius=”md” size=”48px” align=”center” justify=”center”> <icon name=”shopping-cart” size=”xl” color=”#137333″/> </box> <box flex=”1″ gap={1}> **Order Service** <text color=”secondary” size=”sm”>Port: 8081 ยท Returns order information</text> </box> </row> <divider color=”subtle”/> <row align=”center” gap={3}> <box background=”#F3E8FF” radius=”md” size=”48px” align=”center” justify=”center”> <icon name=”git-branch” size=”xl” color=”#6B21A8″/> </box> <box flex=”1″ gap={1}> **API Gateway** <text color=”secondary” size=”sm”>Port: 8083 ยท Routes client requests</text> </box> </row> </box>
We will first use fixed service URLs because they are easy to understand. Later, we will connect the gateway to Eureka for service discovery and load balancing.
Step 1: Create Product Service
Create a Spring Boot application named product-service.
Add Spring Web as a dependency.
Create the controller:
@RestController
@RequestMapping("/products")
public class ProductController {
@GetMapping("/{id}")
public ResponseEntity<String> getProduct(
@PathVariable String id) {
return ResponseEntity.ok(
"Product details for ID: " + id
);
}
}
Configure application.properties:
server.port=8082
spring.application.name=product-service
Now Product Service runs on port 8082.
Its endpoint is:
http://localhost:8082/products/101
The response will be:
Product details for ID: 101
Step 2: Create Order Service
Create another Spring Boot application named order-service.
Add Spring Web as a dependency.
Create the controller:
@RestController
@RequestMapping("/orders")
public class OrderController {
@GetMapping("/{id}")
public ResponseEntity<String> getOrder(
@PathVariable String id) {
return ResponseEntity.ok(
"Order details for ID: " + id
);
}
}
Configure application.properties:
server.port=8081
spring.application.name=order-service
The direct endpoint is:
http://localhost:8081/orders/101
The response will be:
Order details for ID: 101
Now both microservices are ready.
Step 3: Create the API Gateway Application
Create a third Spring Boot application named api-gateway.
Add the Spring Cloud Gateway dependency to its pom.xml:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
Use a Spring Boot and Spring Cloud release combination that is compatible with this dependency.
Now configure application.properties:
spring.application.name=apigateway
server.port=8083
# Route requests to Product Service
spring.cloud.gateway.routes[0].id=product-service
spring.cloud.gateway.routes[0].uri=http://localhost:8082
spring.cloud.gateway.routes[0].predicates[0]=Path=/products/**
# Route requests to Order Service
spring.cloud.gateway.routes[1].id=order-service
spring.cloud.gateway.routes[1].uri=http://localhost:8081
spring.cloud.gateway.routes[1].predicates[0]=Path=/orders/**
That’s it! We have configured our first API Gateway.
Let’s understand the configuration.
spring.cloud.gateway.routes[0].id
This gives the route a unique name.
spring.cloud.gateway.routes[0].uri
This specifies the destination to which the gateway forwards the request.
spring.cloud.gateway.routes[0].predicates[0]
This defines the condition that determines whether a request matches the route.
For example:
Path=/products/**
means requests whose paths match /products/ and its subpaths are eligible for this route.
Similarly:
Path=/orders/**
matches the Order Service route.
5. How Does API Gateway Route Requests?
Let’s start all three applications.
Now send the following requests from Postman or your browser.
<box border radius=”lg” padding={3} gap={3}> <box gap={1}> <row align=”center” gap={2}> <badge color=”success”>GET</badge> **Product request** </row> <text color=”secondary” size=”sm”>Request sent to the gateway</text> <text weight=”medium”>http://localhost:8083/products/101</text> <box background=”surface-secondary” radius=”md” padding={2}> <text size=”sm”>Gateway matches `/products/**` and forwards the request to Product Service on port 8082.</text> </box> <text color=”success” size=”sm”>Expected response: Product details for ID: 101</text> </box> <divider color=”subtle”/> <box gap={1}> <row align=”center” gap={2}> <badge color=”success”>GET</badge> **Order request** </row> <text color=”secondary” size=”sm”>Request sent to the gateway</text> <text weight=”medium”>http://localhost:8083/orders/101</text> <box background=”surface-secondary” radius=”md” padding={2}> <text size=”sm”>Gateway matches `/orders/**` and forwards the request to Order Service on port 8081.</text> </box> <text color=”success” size=”sm”>Expected response: Order details for ID: 101</text> </box> </box>
Notice something important.
We are sending both requests to port 8083, even though Product Service runs on 8082 and Order Service runs on 8081.
The client only needs to know the gateway address for these requests.
That is the main benefit of a single entry point.
6. What Is Service Discovery and Load Balancing in API Gateway?
So far, we have configured fixed URLs:
spring.cloud.gateway.routes[0].uri=http://localhost:8082
But imagine Product Service has three instances running:
Product Service
|
+---- Instance 1: Port 8082
|
+---- Instance 2: Port 8084
|
+---- Instance 3: Port 8085
If we use a fixed URL, we are pointing to only one destination.
How can the gateway discover and distribute requests across multiple instances?
We can use Eureka for service discovery and Spring Cloud LoadBalancer for client-side load balancing.
Step 1: Register services with Eureka
Add the Eureka Client dependency to Product Service and Order Service:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
Configure Product Service:
server.port=8082
spring.application.name=product-service
eureka.client.service-url.defaultZone=http://localhost:8761/eureka
Configure Order Service:
server.port=8081
spring.application.name=order-service
eureka.client.service-url.defaultZone=http://localhost:8761/eureka
You also need a Eureka Server application running on port 8761.
Its main class can be configured with @EnableEurekaServer, and its properties can include:
spring.application.name=eureka-server
server.port=8761
eureka.client.register-with-eureka=false
eureka.client.fetch-registry=false
Step 2: Add Eureka Client to API Gateway
Add the same Eureka Client dependency to API Gateway.
Configure the routes like this:
spring.application.name=apigateway
server.port=8083
spring.cloud.gateway.routes[0].id=product-service
spring.cloud.gateway.routes[0].uri=lb://product-service
spring.cloud.gateway.routes[0].predicates[0]=Path=/products/**
spring.cloud.gateway.routes[1].id=order-service
spring.cloud.gateway.routes[1].uri=lb://order-service
spring.cloud.gateway.routes[1].predicates[0]=Path=/orders/**
eureka.client.service-url.defaultZone=http://localhost:8761/eureka
Here, lb:// is important.
For example:
spring.cloud.gateway.routes[0].uri=lb://product-service
This tells Spring Cloud Gateway to resolve the service name through the service-instance information and use Spring Cloud LoadBalancer to choose an instance.
The flow becomes:
Client
|
v
API Gateway
|
v
Eureka Service Discovery
|
v
Spring Cloud LoadBalancer
|
+----> Product Instance 1
+----> Product Instance 2
+----> Product Instance 3
Make sure the required Spring Cloud LoadBalancer dependency is available through your compatible Spring Cloud setup.
Remember the difference:
- Eureka helps discover available service instances.
- Spring Cloud LoadBalancer selects an instance.
- API Gateway routes the incoming request.
7. What Are Filters in API Gateway?
Now imagine you enter a shopping mall.
Before you enter, security checks your identity card.
Inside the mall, some shops may have additional rules.
API Gateway filters work in a similar way.
A filter can inspect or modify an HTTP request or response as it passes through the gateway.
Filters are useful for authentication, header changes, retries, rate limiting, and Circuit Breaker integration.
There are two important types of filters in your API Gateway material.
7.1 Global Filters
Global filters apply across routes handled by the gateway, subject to their implementation and any explicit exclusions.
For example, you can create a global filter to check JWT authentication for incoming requests.
Client
|
v
Global Authentication Filter
|
v
Route Matching
|
v
Microservice
A global authentication filter can reject a request before it reaches a protected microservice.
Your second PDF demonstrates a custom GlobalFilter and Ordered implementation for this purpose.
7.2 Route-Specific Filters
Route-specific filters apply to particular configured routes.
For example, we may want to add a header only when a request goes to Product Service.
spring.cloud.gateway.routes[0].id=product-service
spring.cloud.gateway.routes[0].uri=lb://product-service
spring.cloud.gateway.routes[0].predicates[0]=Path=/products/**
spring.cloud.gateway.routes[0].filters[0].name=AddRequestHeader
spring.cloud.gateway.routes[0].filters[0].args.name=X-Test-RequestHeader
spring.cloud.gateway.routes[0].filters[0].args.value=ApiGatewayRequest
This adds the X-Test-RequestHeader header with the value ApiGatewayRequest to requests passing through that route.
Other useful route-specific filters include:
| Filter | Purpose |
|---|---|
AddRequestHeader |
Adds a request header |
AddResponseHeader |
Adds a response header |
RemoveRequestHeader |
Removes a request header |
RemoveResponseHeader |
Removes a response header |
Retry |
Retries eligible failed requests |
RequestRateLimiter |
Limits request rates |
CircuitBreaker |
Protects against repeated failures |
These filters make it possible to apply common behavior without duplicating the same logic inside every microservice.
8. How Does JWT Authentication Work in API Gateway?
Imagine a shopping mall where only customers with valid entry passes are allowed into certain areas.
A JWT token is like a digital entry pass.
The client sends the token in the HTTP Authorization header.
For example:
Authorization: Bearer your-jwt-token
The gateway checks the token before forwarding the request to a protected service.
Client
|
| Request + JWT
v
API Gateway
|
v
JWT Validation
|
+---- Invalid token ---> 401 Unauthorized
|
+---- Valid token -----> Microservice
A custom global filter can inspect the Authorization header, validate the token, and reject missing or invalid credentials.
However, simply checking whether a header exists is not enough. The gateway must properly verify the token’s signature and relevant claims, including expiration and issuer where applicable.
Public authentication endpoints may need to be excluded from JWT validation, as shown in your PDF.
Also, downstream services may need their own security checks depending on your architecture. Do not assume that exposing only the gateway automatically secures every internal service.
9. What Is Retry Filter?
Imagine you call a shop, but the shopkeeper temporarily fails to answer.
You try again.
This is the basic idea of Retry.
In API Gateway, a Retry filter can repeat an eligible request when the configured failure conditions are met.
For example, the following configuration requests up to four retries for GET and DELETE requests:
spring.cloud.gateway.routes[0].id=product-service
spring.cloud.gateway.routes[0].uri=lb://product-service
spring.cloud.gateway.routes[0].predicates[0]=Path=/products/**
spring.cloud.gateway.routes[0].filters[0].name=Retry
spring.cloud.gateway.routes[0].filters[0].args.retries=4
spring.cloud.gateway.routes[0].filters[0].args.methods=GET,DELETE
The example demonstrates the method and retry-count settings from your PDF. The exact conditions that trigger retries depend on the filter configuration and framework version.
Important: Four retries can mean up to five total attempts when the initial attempt is included.
Retry should be used carefully, especially for operations that create orders or process payments. Repeating a non-idempotent operation can cause duplicate effects unless the application has appropriate protections.
10. What Is Circuit Breaker Filter?
Imagine a shop has closed because of a serious problem.
You visit the shop repeatedly, but it remains unavailable.
Instead of continuing to visit, you stop trying for a while.
This is the idea behind Circuit Breaker.
When the configured failure threshold is reached, the Circuit Breaker opens and stops normal calls to the protected downstream operation.
After a waiting period, it can allow a limited number of test calls to determine whether the service has recovered.
In Spring Cloud Gateway, you can configure a Circuit Breaker route filter with a fallback endpoint.
For example:
spring.cloud.gateway.routes[0].id=product-service
spring.cloud.gateway.routes[0].uri=lb://product-service
spring.cloud.gateway.routes[0].predicates[0]=Path=/products/**
spring.cloud.gateway.routes[0].filters[0].name=CircuitBreaker
spring.cloud.gateway.routes[0].filters[0].args.name=myCircuitBreakerName
spring.cloud.gateway.routes[0].filters[0].args.fallbackUri=forward:/fallback
The fallback URI tells the gateway to forward the failed operation to a local fallback handler.
A simple fallback controller could look like this:
@RestController
public class FallbackController {
@GetMapping("/fallback")
public ResponseEntity<String> fallback() {
return ResponseEntity
.status(HttpStatus.SERVICE_UNAVAILABLE)
.body("Service is temporarily unavailable. Please try again later.");
}
}
This example uses @RestController so that the returned string becomes the response body.
You also need the Spring Cloud CircuitBreaker Resilience4j integration dependency and compatible Circuit Breaker configuration, as described in your PDF.
Remember that a fallback does not mean the original business operation succeeded. It communicates that the service could not complete the requested operation normally.
11. What Is Rate Limiting?
Imagine a shop can serve only 100 customers per minute.
If 10,000 customers arrive simultaneously, the shop may become overwhelmed.
Rate limiting helps control how many requests are accepted within a specified period.
For example, a gateway might limit a particular client to 100 requests per minute, depending on the configured policy.
Client
|
v
API Gateway
|
v
Rate Limiter
|
+---- Within limit ----> Microservice
|
+---- Limit exceeded --> Rejection response
Spring Cloud Gateway provides a RequestRateLimiter filter.
The actual configuration depends on the selected rate-limiting implementation, such as a Redis-backed limiter, and the application’s client identification and key-resolution rules.
Rate limiting helps protect services from excessive traffic, but it is not a replacement for authentication or broader security controls.
12. How Do API Gateway Filters Execute?
You might wonder what happens when a request passes through multiple filters.
For example:
- Authentication
- Request-header modification
- Retry or Circuit Breaker handling
- Routing to the destination
The order of filter execution matters.
In Spring Cloud Gateway, filters have ordering rules. A lower order value generally means higher priority, so an order of -1 executes before an order of 0.
However, actual execution also depends on the framework’s built-in filters and their defined ordering.
Conceptually, a request passes through the applicable filter chain before reaching the destination. Response processing can then run through the relevant post-processing logic.
This is why custom filters should be assigned an appropriate order when the sequence matters.
13. Advantages and Limitations of API Gateway
Advantages
- Provides a single entry point for clients.
- Centralizes request routing.
- Can integrate with service discovery and load balancing.
- Supports authentication and request filtering.
- Can apply rate limiting and resilience policies.
- Helps centralize logging and monitoring.
Limitations
- Adds an additional network hop.
- Requires careful configuration and monitoring.
- Can become a bottleneck if not scaled appropriately.
- A gateway outage can affect access to multiple services if there is no suitable redundancy.
- Poorly designed filters can introduce latency or security problems.
For production environments, consider multiple gateway instances, health monitoring, suitable timeouts, secure configuration, and proper observability.
14. Final Summary
Let’s remember everything using the shopping mall example.
| Concept | Easy meaning |
|---|---|
| API Gateway | Main entrance to the mall |
| Routing | Directing you to the correct shop |
| Eureka | Finding which shops are available |
| Load Balancer | Distributing customers among available shop instances |
| JWT Authentication | Checking the entry pass |
| Rate Limiting | Limiting how many customers can enter |
| Retry | Trying again after an eligible failure |
| Circuit Breaker | Temporarily stopping calls to an unhealthy shop |
| Filters | Security checks and rules applied to requests or responses |
The most important thing to remember:
An API Gateway is not just a router. It provides a central place to manage how client requests enter a microservices system and can apply additional policies such as authentication, rate limiting, and resilience.
With Spring Cloud Gateway, we can configure routes using application.properties, connect services through Eureka, distribute traffic using Spring Cloud LoadBalancer, and apply filters to handle common requirements.
Once you understand these fundamentals, implementing API Gateway in a real Spring Boot microservices project becomes much easier.
Happy coding! ๐ป