API Gateway: Arquitetura, Padrões e Quando Usar
Entenda o que é um API Gateway, seus padrões arquiteturais, casos de uso, diferença de BFF, e como implementar com Kong, AWS API Gateway ou código próprio.
O que é um API Gateway e qual problema ele resolve
Um API Gateway é um servidor de borda que atua como ponto único de entrada para todas as requisições externas que chegam a uma aplicação. Em vez de clientes chamarem serviços internos diretamente, eles chamam o gateway, que roteia, autentica, transforma e protege as requisições.
Internet
│
┌──────▼──────┐
│ API Gateway│ ← autenticação, rate limit, roteamento
└──────┬──────┘
┌──────┼──────────────┐
▼ ▼ ▼
Serv. A Serv. B Serv. C
(usuário) (pedidos) (produtos)
Sem gateway, cada serviço precisaria implementar autenticação, CORS, logging, rate limiting independentemente — duplicação cara e inconsistente.
Responsabilidades de um API Gateway
Roteamento
Mapeia endpoints externos para serviços internos:
# Kong Gateway - roteamento declarativo
services:
- name: user-service
url: http://users:3001
routes:
- paths: ["/api/users"]
methods: ["GET", "POST", "PUT", "DELETE"]
- name: order-service
url: http://orders:3002
routes:
- paths: ["/api/orders"]
- name: product-service
url: http://products:3003
routes:
- paths: ["/api/products"]
Autenticação centralizada
JWT verificado no gateway — serviços internos recebem apenas requisições já autenticadas:
// Middleware de autenticação no gateway (exemplo genérico)
async function authMiddleware(req, res, next) {
const token = req.headers.authorization?.replace('Bearer ', '')
if (!token) return res.status(401).json({ error: 'Token required' })
try {
const payload = jwt.verify(token, process.env.JWT_SECRET)
// Injeta userId no header para serviços downstream
req.headers['x-user-id'] = payload.sub
req.headers['x-user-role'] = payload.role
next()
} catch {
res.status(401).json({ error: 'Invalid token' })
}
}
Rate limiting
Proteção contra abuso sem alterar serviços:
# Rate limiting por rota no Kong
plugins:
- name: rate-limiting
route: { id: order-service-route }
config:
minute: 100
hour: 1000
policy: local
fault_tolerant: true
Transformação de requisições/respostas
Adapta formatos sem mudar os serviços:
// Normalizar resposta antes de enviar ao cliente
function transformResponse(upstreamResponse) {
return {
data: upstreamResponse.items,
meta: {
total: upstreamResponse.total_count,
page: upstreamResponse.current_page,
}
}
}
API Gateway vs BFF (Backend for Frontend)
| Aspecto | API Gateway | BFF | |---|---|---| | Propósito | Infraestrutura (roteamento, auth, segurança) | Produto (agrega e adapta dados para um frontend específico) | | Quem mantém | Time de plataforma | Time de produto/feature | | Número | 1 (ou poucos) | 1 por tipo de cliente (web, mobile, TV) | | Lógica de negócio | Não deve ter | Pode ter |
┌─────────────┐ ┌──────────────────┐
│ API Gateway │────│ BFF Web │──→ Serviço A
│ (auth, rate)│ │ (agrega A + B) │──→ Serviço B
└─────────────┘ └──────────────────┘
┌──────────────────┐
│ BFF Mobile │──→ Serviço B
│ (subset de dados│──→ Serviço C
│ otimizado) │
└──────────────────┘
É possível (e comum) usar ambos: gateway na borda para infraestrutura, BFF para composição de dados.
Quando usar cada opção
Kong (open source)
- Melhor para: microservices on-premises ou Kubernetes
- Pontos fortes: plugins, performance, extensibilidade
- Complexidade: média (requer Postgres e configuração)
# Quick start com Docker
docker run -d --name kong-database \
-e POSTGRES_USER=kong \
-e POSTGRES_DB=kong \
postgres:15
docker run -d --name kong \
-e KONG_DATABASE=postgres \
-e KONG_PG_HOST=kong-database \
-p 8000:8000 \ # proxy
-p 8001:8001 \ # admin API
kong/kong-gateway:3.6
AWS API Gateway
- Melhor para: workloads na AWS, serverless (Lambda)
- Pontos fortes: integração zero com AWS, escalabilidade automática
- Custo: por chamada ($3.50/1M requests), pode ficar caro
Traefik
- Melhor para: Kubernetes, Docker Swarm
- Pontos fortes: auto-discovery de serviços via labels Docker/K8s
# Traefik via Docker labels
labels:
- "traefik.enable=true"
- "traefik.http.routers.users.rule=PathPrefix(`/api/users`)"
- "traefik.http.middlewares.auth.forwardauth.address=http://auth:5000"
- "traefik.http.routers.users.middlewares=auth"
Nginx como gateway simples
Para projetos menores sem necessidade de features avançadas:
upstream user_service { server users:3001; }
upstream order_service { server orders:3002; }
server {
listen 80;
location /api/users {
auth_request /auth;
proxy_pass http://user_service;
proxy_set_header X-Forwarded-For $remote_addr;
}
location /api/orders {
auth_request /auth;
proxy_pass http://order_service;
}
location = /auth {
internal;
proxy_pass http://auth_service:3000/verify;
}
}
Armadilhas comuns
- Gateway como monolito: não coloque lógica de negócio no gateway — ele deve ser infraestrutura
- Cascata de falhas: se o gateway cair, tudo cai. Configure alta disponibilidade com pelo menos 2 instâncias
- Ponto único de latência: cada hop adiciona latência; monitore o p99 do gateway separadamente
- Segredos no gateway: não configure credenciais de serviços internos no gateway — use uma secret store (Vault, AWS Secrets Manager)
- Logging insuficiente: o gateway tem visibilidade de tudo — aproveite para logar correlation IDs, trace IDs e tempos de resposta upstream
