API gateway
Routing, aggregation, cross-cutting concerns.
An API gateway is the single front door to a fleet of backend services. It routes, authenticates, rate-limits, transforms, and aggregates — so each backend can focus on its domain and clients only need to know one URL.
The big idea
Without a gateway, every client must know which service handles which call, and every service must implement its own auth, rate limiting, logging, and CORS. With one, those concerns live in one place.
What a gateway actually does
Routing
Map
/api/users/*→ users-svc,/api/orders/*→ orders-svc. Path, host, header, or method-based.Authentication + authorization
Verify the JWT or session, attach the user context, reject early on failure.
Rate limiting + quota
By API key, by user, by endpoint. Reject before the backend wastes work.
Request / response transformation
Add headers, strip internal-only fields, version-translate.
Aggregation / composition
One client call fans out to N backend calls, response combined. Hides backend granularity from clients.
Observability
Centralised access logs, metrics, tracing entry point.
Resilience
Retries, circuit breakers, fallback responses.
BFF — Backend for Frontend
A specialised gateway per client type. The mobile app and the web app have different needs (payload size, screen-specific aggregations); a single "one-size-fits-all" gateway forces both clients to compromise.
Each BFF is owned by the frontend team that uses it. That ownership is the whole point — frontend changes don't queue behind backend roadmaps.
Aggregation example
Mobile screen needs: user profile, recent orders, recommended products. Three backend calls. Naive client: 3 round trips over mobile network. Gateway aggregation: 1 round trip.
// inside the gateway
app.get('/api/mobile/home', async (req, res) => {
const [user, orders, recs] = await Promise.all([
usersClient.get(req.user.id),
ordersClient.recent(req.user.id, 5),
recsClient.forUser(req.user.id),
]);
res.json({ user, orders, recs });
});# inside the gateway (FastAPI)
@app.get("/api/mobile/home")
async def home(request: Request):
user, orders, recs = await asyncio.gather(
users_client.get(request.user.id),
orders_client.recent(request.user.id, 5),
recs_client.for_user(request.user.id),
)
return {"user": user, "orders": orders, "recs": recs}What to put in a gateway — and what not to
Auth, rate limit, CORS, gzip, request logging, simple aggregation, header transformation. Cross-cutting concerns that touch every service.
Business logic. The moment your gateway "approves an order" or "deducts inventory," you've built a distributed monolith — a gateway that requires deploying with the backends. Keep behaviour in the owning service.
Build vs buy
You almost certainly should not build one from scratch. The mature options:
- Cloud-managed
- AWS API Gateway, Google Cloud Endpoints, Azure APIM. Zero ops, vendor-shaped.
- Open-source data plane
- Envoy, NGINX, HAProxy. Fast L7 proxies; configuration is the hard part.
- Open-source full gateway
- Kong, Tyk, Krakend, APISIX. Plugins, admin UIs, batteries included.
- Service mesh
- Istio, Linkerd. East-west traffic + sidecar-based; can replace the gateway for internal calls.
In practice
The gateway is one of the highest-leverage components. Done well, it makes adding a new service trivial (declare a route, you're done). Done poorly, it becomes a fragile choke point: every team needs to coordinate gateway changes, deploys are scary, and the "add a new endpoint" ticket is open for two weeks.
Key takeaways
- An API gateway is the single front door for cross-cutting concerns — auth, rate limit, logging.
- BFFs (one per client type) own client-shaped aggregation; the team that uses it owns it.
- Aggregating backend calls in the gateway saves round trips for mobile clients.
- Keep business logic *out* of the gateway; it belongs in the owning service.
- Buy, don't build — mature managed and OSS gateways exist for a reason.
Checkpoint questions
Use these to test whether the lesson is clear enough to explain without rereading.
- 1Which concerns are appropriate for an API gateway, and which should stay in services?
- 2How does a Backend for Frontend differ from a general gateway?
- 3What happens when one downstream service is slow during aggregation?
- 4When should you buy or adopt a gateway product instead of building one from scratch?
References
External resources for going deeper after the lesson above.