API Gateway System Design (HLD and LLD)
What is an API Gateway?
Section titled “What is an API Gateway?”An API Gateway is a single entry point for all client requests that routes them to the appropriate microservices while handling common cross-cutting concerns.
Typical responsibilities include:
- Authentication and authorization
- Request routing
- Rate limiting
- Load balancing
- Request/response transformation
- Caching
- Logging and monitoring
Conceptual Architecture
Section titled “Conceptual Architecture”flowchart LR
C[Client] --> G[API Gateway]
G --> U[User Service]
G --> O[Order Service]
G --> P[Payment Service]
Popular implementations:
- Kong
- Netflix Zuul
- Spring Cloud Gateway
- AWS API Gateway
- NGINX
Functional Requirements
Section titled “Functional Requirements”- Route requests to the correct microservice.
- Authenticate users (JWT/OAuth).
- Rate limit requests.
- Load balance traffic.
- Aggregate responses (optional).
- Cache responses.
- Log requests and expose monitoring metrics.
Non-Functional Requirements
Section titled “Non-Functional Requirements”- High availability
- Low latency
- High throughput
- Horizontal scalability
- Security
- Fault tolerance
High-Level Design (HLD)
Section titled “High-Level Design (HLD)”Overall Architecture
Section titled “Overall Architecture”flowchart TD
Client --> Gateway[API Gateway]
Gateway --> Auth[Authentication]
Gateway --> RL[Rate Limiter]
Gateway --> Router[Router]
Gateway --> Cache[Cache]
Gateway --> Logs[Logging]
Router --> UserSvc[User Service]
Router --> OrderSvc[Order Service]
Router --> PaymentSvc[Payment Service]
Core Components
Section titled “Core Components”Request Router
Section titled “Request Router”Determines which service should handle the request.
Example mappings:
/api/users/** -> User Service/api/orders/** -> Order Service/api/payments/** -> Payment ServiceRouting information may be stored in:
- Configuration
- Service Registry (Eureka/Consul)
Authentication Module
Section titled “Authentication Module”Validates:
- JWT tokens
- OAuth tokens
- API keys
sequenceDiagram
participant C as Client
participant G as Gateway
participant A as Auth
participant S as Service
C->>G: Request + JWT
G->>A: Validate token
A-->>G: Valid
G->>S: Forward request
S-->>G: Response
G-->>C: Response
Rate Limiter
Section titled “Rate Limiter”Protects backend services.
Common algorithms:
- Token Bucket
- Leaky Bucket
- Sliding Window
- Fixed Window
Example policy:
100 requests/minute/userStorage:
- Redis
- In-memory cache
See the Rate Limiter system design case study for the full algorithm comparison and implementation.
Load Balancer
Section titled “Load Balancer”Routes traffic across service instances.
Order Service- Instance 1- Instance 2- Instance 3Algorithms:
- Round Robin
- Least Connections
- Weighted Routing
Caching Layer
Section titled “Caching Layer”Used primarily for:
- GET requests
- Static responses
Example:
GET /products
Redis TTL: 30 secondsLogging and Monitoring
Section titled “Logging and Monitoring”Track:
- Request latency
- Error rates
- Traffic volume
Typical tools:
- Prometheus
- Grafana
- ELK Stack
Request Flow
Section titled “Request Flow”flowchart LR
A[Client]
B[Gateway]
C[Authenticate]
D[Rate Limit]
E[Route]
F[Load Balance]
G[Microservice]
H[Response]
A-->B-->C-->D-->E-->F-->G-->H
Flow:
- Client sends request.
- Gateway receives request.
- Authentication filter validates token.
- Rate limiter checks quota.
- Router determines destination.
- Load balancer selects an instance.
- Request is forwarded.
- Response is returned through the gateway.
Low-Level Design (LLD)
Section titled “Low-Level Design (LLD)”Class Structure
Section titled “Class Structure”classDiagram
class ApiGateway {
Router
AuthFilter
RateLimiter
LoadBalancer
CacheManager
}
class Router
class AuthFilter
class RateLimiter
class LoadBalancer
class CacheManager
ApiGateway --> Router
ApiGateway --> AuthFilter
ApiGateway --> RateLimiter
ApiGateway --> LoadBalancer
ApiGateway --> CacheManager
Router
Section titled “Router”class Router {
Map<String, String> routeMap;
public String getService(String path) { if(path.startsWith("/users")) return "USER_SERVICE";
if(path.startsWith("/orders")) return "ORDER_SERVICE";
return null; }}RateLimiter Interface
Section titled “RateLimiter Interface”interface RateLimiter {
boolean allowRequest(String clientId);
}Token Bucket Implementation
Section titled “Token Bucket Implementation”class TokenBucketRateLimiter implements RateLimiter {
private int capacity; private int tokens; private long lastRefillTime;
public synchronized boolean allowRequest(String clientId) {
refill();
if(tokens > 0) { tokens--; return true; }
return false; }
private void refill() { // refill logic }}Authentication Filter
Section titled “Authentication Filter”class AuthFilter {
public boolean authenticate(String token) {
if(token == null) return false;
return JwtUtil.validate(token); }}Round Robin Load Balancer
Section titled “Round Robin Load Balancer”class RoundRobinLoadBalancer {
private List<String> instances; private AtomicInteger index = new AtomicInteger(0);
public String getInstance() {
int i = index.getAndIncrement(); return instances.get(i % instances.size()); }}Cache Manager
Section titled “Cache Manager”class CacheManager {
RedisClient redis;
public String get(String key) { return redis.get(key); }
public void put(String key, String value) { redis.set(key, value); }}Distributed API Gateway
Section titled “Distributed API Gateway”flowchart TD
Clients --> LB[Load Balancer]
LB --> G1[Gateway 1]
LB --> G2[Gateway 2]
LB --> G3[Gateway 3]
G1 --> Services
G2 --> Services
G3 --> Services
Gateway instances should remain stateless.
Shared infrastructure:
- Redis
- Configuration Server
Storage
Section titled “Storage”| Purpose | Storage |
|---|---|
| Rate limiting | Redis |
| Cache | Redis |
| Configuration | Config Server |
Scaling Strategy
Section titled “Scaling Strategy”Horizontal Scaling
Section titled “Horizontal Scaling”Add additional gateway instances behind a load balancer.
Stateless Design
Section titled “Stateless Design”Persist shared state in:
- Redis
- Kafka
- Configuration Server
Failure Handling
Section titled “Failure Handling”Use circuit breakers such as:
- Resilience4j
- Hystrix
Flow:
Gateway -> Service failure -> Circuit opens -> Fallback responseSecurity
Section titled “Security”Typical responsibilities:
- SSL termination
- JWT validation
- OAuth2
- API key validation
- IP whitelisting
- WAF integration
Spring Cloud Gateway Example
Section titled “Spring Cloud Gateway Example”Architecture:
Client |Spring Cloud Gateway |Eureka |MicroservicesExample route:
@BeanRouteLocator routes(RouteLocatorBuilder builder) { return builder.routes() .route("user-service", r -> r.path("/users/**") .uri("lb://USER-SERVICE")) .build();}API Gateway vs Load Balancer
Section titled “API Gateway vs Load Balancer”| Feature | Load Balancer | API Gateway |
|---|---|---|
| Layer | L4/L7 | L7 |
| Routing | Basic | Advanced |
| Authentication | No | Yes |
| Rate Limiting | No | Yes |
| Request Transformation | No | Yes |
Common Interview Questions
Section titled “Common Interview Questions”- How do you implement distributed rate limiting?
- How do you avoid the gateway becoming a bottleneck?
- How do you implement API aggregation?
- How do you handle gateway failures?
- API Gateway vs Service Mesh?
- Why Spring Cloud Gateway instead of Zuul?
Key Takeaways
Section titled “Key Takeaways”- API Gateway centralizes routing, security, rate limiting, caching, logging, and monitoring.
- Gateways should remain stateless to enable horizontal scaling.
- Redis is commonly used for distributed caching and rate limiting.
- Spring Cloud Gateway is a popular Java implementation for microservice ecosystems.
- Circuit breakers and load balancing improve resilience and availability.