API Gateway Pattern
A single entry point that handles routing, auth, rate limiting, and protocol translation for downstream services.
Overview
An API Gateway is a single entry point for all client requests to a backend system. It handles cross-cutting concerns, authentication, rate limiting, SSL termination, request routing, protocol translation, logging, and response transformation, so individual services do not need to implement them independently.
Origin
API gateways emerged as microservices architectures proliferated in the early 2010s. AWS API Gateway (2015) made the pattern accessible at cloud scale. Kong (2015), nginx, and Envoy followed as open-source options. The BFF (Backend For Frontend) pattern extends it: separate gateways optimised for each client type.
Examples
API Gateway responsibilities (nginx as gateway)
// Conceptual gateway middleware stack (Express-style pseudocode)
const gateway = express()
// Cross-cutting concerns handled once, not in each service:
// 1. SSL termination (in practice: nginx handles this upstream)
// 2. Authentication
gateway.use(async (req, res, next) => {
const token = req.headers.authorization?.split(' ')[1]
req.user = await verifyJWT(token)
next()
})
// 3. Rate limiting
gateway.use(rateLimit({ windowMs: 60_000, max: 100, keyGenerator: req => req.user.id }))
// 4. Request routing with service discovery
gateway.use('/users', createProxyMiddleware({ target: serviceRegistry.get('user-service') }))
gateway.use('/orders', createProxyMiddleware({ target: serviceRegistry.get('order-service') }))
// 5. Response transformation / aggregation (BFF pattern)
gateway.get('/dashboard', async (req, res) => {
const [user, orders, notifications] = await Promise.all([
userService.get(req.user.id),
orderService.getRecent(req.user.id),
notificationService.getUnread(req.user.id),
])
res.json({ user, orders, notifications }) // aggregated for the client
})Use Cases
- 01Centralising auth so services trust the gateway and do not each need to verify tokens
- 02Rate limiting and DDoS protection at the perimeter
- 03BFF pattern: aggregating multiple service responses into a single client-optimised payload
- 04Protocol translation: accepting REST from clients and forwarding as gRPC to internal services
When Not to Use
- //Single-service architectures where there is no routing complexity
- //When the gateway becomes a god object that too many teams modify, it must not contain business logic
- //High-throughput, low-latency paths where the additional network hop through the gateway is unacceptable
Technical Notes
- The gateway must not contain business logic, it is infrastructure. Business logic belongs in the services
- A single gateway is a potential single point of failure and a bottleneck: run it with multiple instances behind a load balancer
- GraphQL Federation (Apollo) is a form of API gateway specifically for GraphQL: a supergraph composed from service-specific subgraphs
- Service mesh (Istio, Linkerd) handles east-west traffic (service-to-service); an API gateway handles north-south traffic (client-to-services). Use both together in large deployments
More in Architecture