Introduction
API gateways are critical infrastructure for managing, securing, and scaling APIs. They provide a single entry point for client requests, handling cross-cutting concerns like authentication, rate limiting, and request routing. However, choosing and configuring the right API gateway requires understanding different patterns and trade-offs.
This comprehensive guide covers API gateway patterns, implementations, and real-world strategies.
Core Concepts
API Gateway
Single entry point for client requests that routes to backend services.
Routing
Directing requests to appropriate backend services based on path, host, or other criteria.
Rate Limiting
Restricting number of requests per time period.
Authentication
Verifying client identity.
Authorization
Determining what authenticated clients can access.
Request/Response Transformation
Modifying requests or responses in transit.
Load Balancing
Distributing requests across multiple backend instances.
Circuit Breaking
Preventing cascading failures by stopping requests to failing services.
API Gateway Comparison
| Feature | Kong | AWS API Gateway | Nginx |
|---|---|---|---|
| Type | Self-hosted/Cloud | Managed | Self-hosted |
| Pricing | Free/Enterprise | Pay-per-request | Free |
| Setup | Moderate | Easy | Complex |
| Scalability | Excellent | Unlimited | Good |
| Plugins | 100+ | Limited | Via modules |
| Rate Limiting | Yes | Yes | Yes |
| Authentication | Yes | Yes | Yes |
| Best For | Microservices | AWS-native | High-performance |
Kong Implementation
# Kong configuration
_format_version: "3.0"
_transform: true
services:
- name: user-service
url: http://user-service:8080
routes:
- name: user-api
paths:
- /api/users
methods:
- GET
- POST
strip_path: true
- name: order-service
url: http://order-service:8080
routes:
- name: order-api
paths:
- /api/orders
methods:
- GET
- POST
strip_path: true
plugins:
- name: rate-limiting
service: user-service
config:
minute: 100
hour: 1000
- name: jwt
service: user-service
config:
key_claim_name: sub
secret_is_base64: false
- name: cors
config:
origins:
- "*"
methods:
- GET
- POST
- PUT
- DELETE
headers:
- Content-Type
- Authorization
AWS API Gateway Implementation
import boto3
client = boto3.client('apigateway')
# Create REST API
api = client.create_rest_api(
name='MyAPI',
description='My API Gateway',
endpointConfiguration={'types': ['REGIONAL']}
)
api_id = api['id']
# Get root resource
resources = client.get_resources(restApiId=api_id)
root_id = resources['items'][0]['id']
# Create /users resource
users_resource = client.create_resource(
restApiId=api_id,
parentId=root_id,
pathPart='users'
)
# Create GET method
client.put_method(
restApiId=api_id,
resourceId=users_resource['id'],
httpMethod='GET',
authorizationType='AWS_IAM'
)
# Create integration
client.put_integration(
restApiId=api_id,
resourceId=users_resource['id'],
httpMethod='GET',
type='HTTP',
integrationHttpMethod='GET',
uri='http://user-service:8080/users'
)
# Deploy API
deployment = client.create_deployment(
restApiId=api_id,
stageName='prod'
)
Nginx Implementation
# nginx.conf
upstream user_service {
server user-service:8080;
server user-service-2:8080;
}
upstream order_service {
server order-service:8080;
server order-service-2:8080;
}
# Rate limiting
limit_req_zone $binary_remote_addr zone=api_limit:10m rate=10r/s;
server {
listen 80;
server_name api.example.com;
# User service routes
location /api/users {
limit_req zone=api_limit burst=20 nodelay;
# Authentication
auth_request /auth;
proxy_pass http://user_service;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
# Order service routes
location /api/orders {
limit_req zone=api_limit burst=20 nodelay;
auth_request /auth;
proxy_pass http://order_service;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
# Authentication endpoint
location = /auth {
internal;
proxy_pass http://auth-service:8080/verify;
proxy_pass_request_body off;
proxy_set_header Content-Length "";
proxy_set_header X-Original-URI $request_uri;
}
}
API Gateway Patterns
Request Routing
# Route based on path
/api/v1/users -> user-service
/api/v1/orders -> order-service
/api/v1/products -> product-service
# Route based on host
users.api.example.com -> user-service
orders.api.example.com -> order-service
# Route based on header
X-Service: users -> user-service
X-Service: orders -> order-service
Rate Limiting
# Token bucket algorithm
class RateLimiter:
def __init__(self, rate, capacity):
self.rate = rate # tokens per second
self.capacity = capacity
self.tokens = capacity
self.last_update = time.time()
def allow_request(self):
now = time.time()
elapsed = now - self.last_update
# Add tokens
self.tokens = min(
self.capacity,
self.tokens + elapsed * self.rate
)
self.last_update = now
if self.tokens >= 1:
self.tokens -= 1
return True
return False
# Usage
limiter = RateLimiter(rate=10, capacity=100) # 10 req/sec, burst 100
if limiter.allow_request():
# Process request
pass
else:
# Return 429 Too Many Requests
pass
Circuit Breaker
from enum import Enum
import time
class CircuitState(Enum):
CLOSED = 1
OPEN = 2
HALF_OPEN = 3
class CircuitBreaker:
def __init__(self, failure_threshold=5, timeout=60):
self.failure_threshold = failure_threshold
self.timeout = timeout
self.failure_count = 0
self.last_failure_time = None
self.state = CircuitState.CLOSED
def call(self, func, *args, **kwargs):
if self.state == CircuitState.OPEN:
if time.time() - self.last_failure_time > self.timeout:
self.state = CircuitState.HALF_OPEN
else:
raise Exception("Circuit breaker is OPEN")
try:
result = func(*args, **kwargs)
self.on_success()
return result
except Exception as e:
self.on_failure()
raise e
def on_success(self):
self.failure_count = 0
self.state = CircuitState.CLOSED
def on_failure(self):
self.failure_count += 1
self.last_failure_time = time.time()
if self.failure_count >= self.failure_threshold:
self.state = CircuitState.OPEN
Best Practices
- Single Entry Point: Route all traffic through gateway
- Authentication: Centralize authentication
- Rate Limiting: Protect backend services
- Monitoring: Track gateway metrics
- Caching: Cache responses when possible
- Circuit Breaking: Prevent cascading failures
- Request Transformation: Normalize requests
- Error Handling: Consistent error responses
- Versioning: Support multiple API versions
- Documentation: Document all routes
External Resources
Kong
AWS API Gateway
Nginx
Conclusion
API gateways are essential infrastructure for managing APIs at scale. Choose based on your requirements: Kong for flexibility, AWS API Gateway for AWS-native deployments, Nginx for high performance.
Implement proper rate limiting, authentication, and monitoring to ensure reliable API operations.
API gateways are the foundation of scalable API infrastructure.
Comments