API Gateway Pattern: Architecture, Tools & When to Use One
API Gateway Pattern: Architecture, Tools & When to Use One#
Every request from a client to your microservices has to go somewhere first. The API gateway pattern puts a single entry point between consumers and your backend services, handling cross-cutting concerns so your services don't have to.
What Does an API Gateway Do?#
An API gateway accepts all incoming API calls, routes them to the appropriate backend service, and applies policies along the way. It decouples clients from the internal service topology.
┌──────────┐ ┌──────────────┐ ┌────────────┐
│ Mobile │──────▶│ │──────▶│ Users API │
│ Web App │──────▶│ API Gateway │──────▶│ Orders API │
│ Partner │──────▶│ │──────▶│ Search API │
└──────────┘ └──────────────┘ └────────────┘
│ Auth │
│ Rate Limit │
│ Transform │
│ Circuit Break│
Without a gateway, every service must independently handle authentication, rate limiting, logging, and protocol translation — a recipe for duplication and drift.
Core Patterns#
1. Request Routing#
The gateway inspects the path, headers, or method and forwards the request to the correct upstream service.
# Kong declarative config
services:
- name: users-service
url: http://users:8080
routes:
- paths: ["/api/users"]
methods: ["GET", "POST"]
- name: orders-service
url: http://orders:8080
routes:
- paths: ["/api/orders"]
2. Rate Limiting#
Protect backends from traffic spikes by enforcing request quotas per consumer or IP.
plugins:
- name: rate-limiting
config:
minute: 100
policy: redis
redis_host: redis
3. Authentication & Authorization#
Validate JWTs, API keys, or OAuth tokens at the edge so services receive only authenticated traffic.
plugins:
- name: jwt
config:
claims_to_verify: ["exp"]
header_names: ["Authorization"]
4. Request & Response Transformation#
Reshape payloads between what clients send and what services expect — rename fields, strip headers, aggregate responses.
5. Circuit Breaking#
When a downstream service is failing, the gateway stops forwarding traffic and returns a fallback response, preventing cascading failures.
Client ──▶ Gateway ──✕──▶ Failing Service
│
└──▶ 503 + fallback response
6. Observability#
Centralized logging, tracing headers (e.g., X-Request-Id), and metrics collection give you a single pane of glass for all API traffic.
API Gateway vs Reverse Proxy vs Load Balancer#
| Concern | Reverse Proxy | Load Balancer | API Gateway |
|---|---|---|---|
| Primary job | Forward requests | Distribute traffic | Manage API lifecycle |
| Auth / rate limiting | No | No | Yes |
| Request transform | Minimal | No | Yes |
| Protocol translation | Sometimes | No | Yes (REST↔gRPC, etc.) |
| Service discovery | Static upstream | Health-check based | Dynamic registry |
A reverse proxy forwards traffic. A load balancer distributes it. An API gateway manages it — auth, transformation, rate limiting, and more. In practice, many gateways include reverse proxy and load balancing capabilities.
Popular Tools Compared#
Kong#
Open-source, plugin-driven, runs on Nginx/OpenResty. Strong ecosystem, declarative config, enterprise tier with a GUI. Best for teams that want extensibility.
AWS API Gateway#
Fully managed, integrates natively with Lambda, Cognito, and IAM. Two flavors: REST API (feature-rich) and HTTP API (cheaper, faster). Best for AWS-native stacks.
Nginx#
Lightweight reverse proxy that can act as a gateway with additional modules. Excellent raw performance. Requires more manual configuration for API management features.
Envoy#
High-performance L4/L7 proxy designed for service mesh architectures. gRPC-native, dynamic configuration via xDS API. Powers Istio's data plane.
Traefik#
Auto-discovers services from Docker, Kubernetes, and Consul. Zero-config TLS with Let's Encrypt. Best for container-native environments.
┌─────────────────────────────────────┐
│ Decision Matrix │
├─────────────┬───────────┬────────────┤
│ Managed? │ Plugins? │ Mesh-ready?│
├─────────────┼───────────┼────────────┤
│ AWS GW ✓ │ Kong ✓ │ Envoy ✓ │
│ Traefik ~ │ Nginx ~ │ Traefik ~ │
└─────────────┴───────────┴────────────┘
The Backend-for-Frontend (BFF) Pattern#
Instead of one monolithic gateway, deploy a dedicated gateway per client type. A mobile BFF aggregates and slims down responses, while a web BFF serves richer payloads.
┌─────────┐ ┌──────────────┐ ┌────────────┐
│ Mobile │────▶│ Mobile BFF │────▶│ │
└─────────┘ └──────────────┘ │ Backend │
┌─────────┐ ┌──────────────┐ │ Services │
│ Web App │────▶│ Web BFF │────▶│ │
└─────────┘ └──────────────┘ └────────────┘
This avoids the "one gateway fits all" problem where mobile clients download fields they never render.
Kong vs AWS API Gateway#
| Factor | Kong | AWS API Gateway |
|---|---|---|
| Hosting | Self-managed or Kong Cloud | Fully managed |
| Extensibility | 100+ plugins, custom Lua/Go | Limited transforms, Lambda |
| Multi-cloud | Yes | AWS only |
| Cost model | Infrastructure cost | Per-request pricing |
| Best for | Multi-cloud, plugin-heavy | Serverless, AWS-native |
When to Use an API Gateway#
Use a gateway when you have:
- Multiple microservices behind a single domain
- Cross-cutting concerns (auth, rate limiting, logging) you don't want duplicated
- Different client types needing different response shapes
- External API consumers who need key management and throttling
Skip a gateway when:
- You have a monolith with one or two endpoints
- Internal service-to-service calls only (use a service mesh instead)
- You're adding complexity without a clear operational benefit
Quick Start: Minimal Kong + Docker#
# docker-compose.yml
version: "3"
services:
kong:
image: kong:3.6
environment:
KONG_DATABASE: "off"
KONG_DECLARATIVE_CONFIG: /etc/kong/kong.yml
KONG_PROXY_LISTEN: "0.0.0.0:8000"
ports:
- "8000:8000"
volumes:
- ./kong.yml:/etc/kong/kong.yml
# kong.yml
_format_version: "3.0"
services:
- name: my-api
url: http://host.docker.internal:3000
routes:
- paths: ["/"]
plugins:
- name: rate-limiting
config:
minute: 60
Run docker compose up and every request to localhost:8000 is routed through the gateway with rate limiting applied.
Key Takeaways#
- An API gateway centralizes routing, auth, rate limiting, and observability at the edge.
- It is not a replacement for a load balancer or service mesh — each solves a different layer.
- Choose managed (AWS API Gateway) for simplicity, open-source (Kong, Envoy) for control.
- Use the BFF pattern when different clients need fundamentally different API shapes.
- Start simple — add gateway features incrementally as operational needs grow.
Design your API architecture at codelit.io.
126 articles on system design at codelit.io/blog.
Try it on Codelit
Chaos Mode
Simulate node failures and watch cascading impact across your architecture
Related articles
Try these templates
Scalable SaaS Application
Modern SaaS with microservices, event-driven processing, and multi-tenant architecture.
10 componentsAPI Gateway Platform
Kong/AWS API Gateway-like platform with routing, auth, rate limiting, transformation, and developer portal.
8 componentsGraphQL API Gateway
Federated GraphQL gateway aggregating multiple microservice schemas with caching, auth, and rate limiting.
10 components
Comments