Padrões e Estratégias de Implementação de API Gateway
API gateways servem como o único ponto de entrada para aplicações cliente acessarem microsserviços, fornecendo preocupações transversais essenciais como autenticação, limitação de taxa, roteamento e monitoramento. Compreender padrões de gateway é crucial para construir sistemas distribuídos escaláveis e seguros.
Arquitetura Central de API Gateway
Posicionamento de Gateway em Microsserviços
API Gateway como Único Ponto de Entrada:
Internet ──► API Gateway ──► Service Registry
│ │ │
▼ ▼ ▼
Clients ──────────┼───────────────┼─► Microsserviço A
│ │
└───────────────┼─► Microsserviço B
│
└─► Microsserviço C
Responsabilidades do Gateway:
- Roteamento de Solicitações: Direcionar solicitações para serviços apropriados
- Autenticação: Validar credenciais e permissões do usuário
- Limitação de Taxa: Controlar taxas de solicitação para prevenir abuso
- Balanceamento de Carga: Distribuir solicitações entre instâncias de serviço
- Monitoramento: Rastrear métricas de solicitação e saúde
Padrões de Roteamento
Roteamento Baseado em Caminho
Mapeamento de Caminho URL:
/api/v1/users/* ──► User Service
/api/v1/orders/* ──► Order Service
/api/v1/products/* ──► Product Service
Exemplo de Implementação:
location /api/v1/users/ {
proxy_pass http://user-service:8080/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
location /api/v1/orders/ {
proxy_pass http://order-service:8080/;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
Roteamento Baseado em Cabeçalho
Roteamento por Content-Type:
Content-Type: application/json ──► JSON Service
Content-Type: application/xml ──► XML Service
Roteamento Baseado em Versão:
X-API-Version: v1 ──► Legacy Service
X-API-Version: v2 ──► Modern Service
Roteamento Dinâmico com Descoberta de Serviço
Integração com Service Registry:
API Gateway ──► Consul/Eureka ──► Service Instances
│ │
└─► Health Check ──► Load Balance ──► Route Request
Autenticação e Autorização
Validação de Token JWT
Fluxo JWT:
Client ──► JWT Token ──► Gateway ──► Validate Token ──► Service
▲ │ │
└──────────────────────┴───────────────┘
Token Refresh
Implementação de Validação de Token:
class JwtAuthMiddleware {
async validateToken(token: string): Promise<UserClaims> {
try {
const decoded = jwt.verify(token, process.env.JWT_SECRET);
return {
userId: decoded.sub,
roles: decoded.roles,
permissions: decoded.permissions
};
} catch (error) {
throw new AuthenticationError('Invalid token');
}
}
async authorizeRequest(claims: UserClaims, requiredRoles: string[]): Promise<boolean> {
return requiredRoles.some(role => claims.roles.includes(role));
}
}
Integração OAuth2
Fluxo de Código de Autorização:
Client ──► Gateway ──► Auth Server ──► User Consent ──► Tokens
▲ │ │ │
└──────────────┼────────────────────┼────────────────────┘
Redirect with Code ──► Exchange for Tokens
Autenticação por Chave API
Acesso Baseado em Chave:
class ApiKeyMiddleware {
private keyStore: Map<string, ApiKeyConfig> = new Map();
async validateApiKey(apiKey: string): Promise<boolean> {
const config = this.keyStore.get(apiKey);
if (!config) return false;
// Check rate limits, expiration, etc.
return config.active && !this.isExpired(config);
}
async getRateLimit(apiKey: string): Promise<RateLimit> {
const config = this.keyStore.get(apiKey);
return config?.rateLimit || { requests: 100, period: '1h' };
}
}
Padrões de Limitação de Taxa
Algoritmo Token Bucket
Implementação Token Bucket:
class TokenBucket {
private tokens: number;
private lastRefill: number;
private readonly capacity: number;
private readonly refillRate: number; // tokens per second
constructor(capacity: number, refillRate: number) {
this.capacity = capacity;
this.refillRate = refillRate;
this.tokens = capacity;
this.lastRefill = Date.now();
}
allowRequest(): boolean {
this.refill();
if (this.tokens >= 1) {
this.tokens--;
return true;
}
return false;
}
private refill(): void {
const now = Date.now();
const timePassed = (now - this.lastRefill) / 1000;
const tokensToAdd = timePassed * this.refillRate;
this.tokens = Math.min(this.capacity, this.tokens + tokensToAdd);
this.lastRefill = now;
}
}
Contador de Janela Deslizante
Limitação de Taxa Distribuída:
class SlidingWindowLimiter {
private redis: Redis;
async isAllowed(key: string, limit: number, windowMs: number): Promise<boolean> {
const now = Date.now();
const windowStart = now - windowMs;
// Remove old entries
await this.redis.zremrangebyscore(key, 0, windowStart);
// Count current requests
const requestCount = await this.redis.zcard(key);
if (requestCount >= limit) {
return false;
}
// Add current request
await this.redis.zadd(key, now, `${now}-${Math.random()}`);
await this.redis.expire(key, Math.ceil(windowMs / 1000));
return true;
}
}
Transformação de Solicitações
Transformação de Dados
Enriquecimento de Solicitação:
Incoming Request ──► Add User Context ──► Service
│ │
└─► {userId: 123} ───────┘
Transformação de Resposta:
Service Response ──► Remove Sensitive Data ──► Client
│ │
└─► Filter Fields ──────────┘
Tradução de Protocolo
REST para GraphQL:
REST API ──► Gateway ──► GraphQL Schema ──► Resolvers
│ │ │
└──────────────┼──────────┘
Query Optimization
Estratégias de Cache
Cache de Resposta
Cabeçalhos de Cache HTTP:
class CacheMiddleware {
async handleRequest(req: Request, res: Response): Promise<void> {
const cacheKey = this.generateCacheKey(req);
// Check cache
const cached = await this.cache.get(cacheKey);
if (cached && this.isCacheValid(cached, req)) {
res.setHeader('X-Cache', 'HIT');
res.send(cached.data);
return;
}
// Set cache headers for response
res.setHeader('Cache-Control', 'public, max-age=300');
res.setHeader('ETag', this.generateETag(res.body));
// Cache the response
await this.cache.set(cacheKey, {
data: res.body,
headers: res.headers,
timestamp: Date.now()
});
}
}
Cache Distribuído
Replicação de Cache:
API Gateway ──► Redis Cluster ──► Cache Hit
│ │
└──────────────┘
Cache Miss → Origin
Padrão Circuit Breaker
Estados do Circuit Breaker
Máquina de Estados:
Closed ──► Open (when failures > threshold)
▲ │
└─────────┼─► Half-Open (test request)
│
└─► Closed (if success)
Implementação:
enum CircuitState {
CLOSED = 'CLOSED',
OPEN = 'OPEN',
HALF_OPEN = 'HALF_OPEN'
}
class CircuitBreaker {
private state: CircuitState = CircuitState.CLOSED;
private failureCount = 0;
private lastFailureTime = 0;
async execute<T>(operation: () => Promise<T>): Promise<T> {
if (this.state === CircuitState.OPEN) {
if (this.shouldAttemptReset()) {
this.state = CircuitState.HALF_OPEN;
} else {
throw new CircuitBreakerError('Circuit is open');
}
}
try {
const result = await operation();
this.onSuccess();
return result;
} catch (error) {
this.onFailure();
throw error;
}
}
private onSuccess(): void {
this.failureCount = 0;
this.state = CircuitState.CLOSED;
}
private onFailure(): void {
this.failureCount++;
this.lastFailureTime = Date.now();
if (this.failureCount >= this.failureThreshold) {
this.state = CircuitState.OPEN;
}
}
}
Monitoramento e Observabilidade
Métricas de Gateway
Métricas Principais a Rastrear:
- Latência de solicitação por endpoint
- Taxas de erro por serviço
- Acertos de limitação de taxa
- Falhas de autenticação
- Taxas de acerto/erro de cache
Coleta de Métricas:
class MetricsCollector {
private metrics: Map<string, Metric> = new Map();
recordRequest(endpoint: string, method: string, statusCode: number, duration: number): void {
const key = `${method}:${endpoint}`;
this.metrics.set(key, {
count: (this.metrics.get(key)?.count || 0) + 1,
totalDuration: (this.metrics.get(key)?.totalDuration || 0) + duration,
statusCodes: {
...this.metrics.get(key)?.statusCodes,
[statusCode]: (this.metrics.get(key)?.statusCodes?.[statusCode] || 0) + 1
}
});
}
getMetrics(): GatewayMetrics {
return {
endpoints: Array.from(this.metrics.entries()).map(([key, metric]) => ({
endpoint: key,
requests: metric.count,
avgLatency: metric.totalDuration / metric.count,
statusCodes: metric.statusCodes
}))
};
}
}
Rastreamento Distribuído
Rastreamento de Solicitação:
Client Request ──► Gateway (span-1) ──► Service A (span-2) ──► Service B (span-3)
│ │ │ │
└─ Trace ID: abc-123 ──┼─ Parent: span-1 ─────┼─ Parent: span-2 ─────┘
Orquestração de Serviço
Composição de API
Agregação de Solicitações:
Gateway ──► Parallel Requests ──► Combine Results
│ ├─► Service A
│ ├─► Service B
│ └─► Service C
│
└─► Single Response
Orquestração Saga
Coordenação de Transação Distribuída:
Gateway ──► Start Saga ──► Service A ──► Service B ──► Complete
│ │ │ │
└─────────┼──────────────┼──────────────┘
Compensate on Failure
Melhores Práticas de Segurança
Validação e Sanitização de Entrada
Validação de Solicitação:
class ValidationMiddleware {
async validateRequest(req: Request): Promise<ValidationResult> {
const schema = this.getSchema(req.path);
try {
const validated = await schema.validate(req.body);
return { valid: true, data: validated };
} catch (error) {
return {
valid: false,
errors: error.errors.map(err => ({
field: err.field,
message: err.message
}))
};
}
}
}
Configuração CORS
Cross-Origin Resource Sharing:
const corsOptions = {
origin: (origin, callback) => {
const allowedOrigins = process.env.ALLOWED_ORIGINS?.split(',') || [];
if (allowedOrigins.includes(origin) || !origin) {
callback(null, true);
} else {
callback(new Error('Not allowed by CORS'));
}
},
credentials: true,
methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'],
allowedHeaders: ['Content-Type', 'Authorization', 'X-API-Key']
};
Otimização de Desempenho
Pooling de Conexões
Configuração de Cliente HTTP:
const httpClient = axios.create({
baseURL: 'http://service-registry',
timeout: 5000,
httpAgent: new http.Agent({
keepAlive: true,
maxSockets: 100,
maxFreeSockets: 10,
timeout: 60000
})
});
Compressão de Resposta
Compressão Gzip:
gzip on;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
gzip_min_length 1024;
gzip_comp_level 6;
Integração com GitScrum
Dashboard de Monitoramento de Gateway
Rastreamento de Saúde de API Gateway:
- Monitorar throughput e latência de solicitação
- Rastrear disponibilidade de serviço e taxas de erro
- Configurar alertas para falhas de gateway
Mapeamento de Dependência de Serviço
Visualização de Dependência:
API Gateway ──► User Service ──► Auth Service
│ │ │
└──────────────┼───────────────┘
Service Mesh Integration