5.3 KiB
5.3 KiB
trigger
| trigger |
|---|
| always_on |
API Gateway Advanced Patterns
When to Use This Skill
Use this skill when:
- Implementing API composition and aggregation
- Transforming requests/responses at gateway level
- Integrating service mesh (Istio/Linkerd) with Traefik
- Implementing advanced routing strategies
- Adding gateway-level circuit breakers
- Implementing API versioning at gateway
- Optimizing gateway performance
Core Concepts
API Gateway Responsibilities
- Request Routing: Route requests to appropriate services
- API Composition: Aggregate multiple service responses
- Protocol Translation: Convert between protocols (HTTP, gRPC, GraphQL)
- Request/Response Transformation: Modify requests and responses
- Security: Authentication, authorization, rate limiting
- Resilience: Circuit breaker, retry, timeout at gateway level
- Observability: Logging, metrics, tracing
API Composition Patterns
- Aggregation: Combine multiple service responses into single response
- Chaining: Call services sequentially, use previous response in next call
- Fan-out/Fan-in: Call multiple services in parallel, aggregate results
Key Patterns
API Composition
// Fan-out: Call multiple services in parallel
async getUserProfile(userId: string) {
const [user, orders, payments] = await Promise.all([
this.userClient.get(`/users/${userId}`),
this.orderClient.get(`/orders?userId=${userId}`),
this.paymentClient.get(`/payments?userId=${userId}`),
]);
return {
user: user.data,
orders: orders.data.orders,
paymentHistory: payments.data.payments,
};
}
// Chaining: Sequential calls with compensation
async createOrderWithPayment(data) {
const order = await this.orderClient.post('/orders', data);
try {
const payment = await this.paymentClient.post('/payments', { orderId: order.data.id });
return { order: order.data, payment: payment.data };
} catch (error) {
await this.orderClient.delete(`/orders/${order.data.id}`); // Compensate
throw error;
}
}
Gateway Caching
export function gatewayCache(ttl: number = 60) {
return async (req, res, next) => {
if (req.method !== 'GET') return next();
const cacheKey = `gateway:${req.path}:${JSON.stringify(req.query)}`;
const cached = await cacheService.get(cacheKey);
if (cached) return res.json(cached);
const originalJson = res.json.bind(res);
res.json = (data) => {
cacheService.set(cacheKey, data, ttl);
return originalJson(data);
};
next();
};
}
Traefik Circuit Breaker
middlewares:
circuit-breaker:
circuitBreaker:
expression: "NetworkErrorRatio() > 0.50"
timeout:
forwardingTimeouts:
dialTimeout: 5s
responseHeaderTimeout: 10s
Best Practices
- API Composition: Use for aggregating related data from multiple services
- Caching: Cache at gateway for frequently accessed data
- Circuit Breaker: Implement at gateway to protect downstream services
- Transformation: Keep transformations simple and testable
- Versioning: Use path-based or header-based versioning
- Monitoring: Monitor gateway metrics (latency, error rate)
Common Mistakes
-
No Timeout at Gateway: Requests hanging forever
# GOOD: Set timeout middlewares: timeout: forwardingTimeouts: dialTimeout: 5s responseHeaderTimeout: 10s -
Missing Circuit Breaker: Cascading failures
# GOOD: Add circuit breaker for each service middlewares: circuit-breaker: circuitBreaker: expression: "NetworkErrorRatio() > 0.50" -
No Caching for Static Data: Unnecessary service load
// GOOD: Cache at gateway app.get('/api/config', gatewayCache(3600), handler); -
N+1 API Calls from Client: Multiple round trips
// BAD: Client makes 3 calls // GOOD: Use API composition GET /user-profile/123
Quick Reference
| Pattern | Use Case | Implementation |
|---|---|---|
| API Composition | Aggregate multiple services | Promise.all() |
| Request Transform | Modify incoming requests | Middleware |
| Response Transform | Standardize responses | Override res.json |
| Gateway Caching | Cache GET responses | Redis/Memory |
| Circuit Breaker | Protect from failures | Traefik middleware |
Traefik Middleware Order:
1. Rate Limiting
2. Authentication
3. Circuit Breaker
4. Retry
5. Headers Transform
6. Compression
API Composition Patterns:
// Fan-out (parallel)
const [users, orders] = await Promise.all([userClient.get('/users'), orderClient.get('/orders')]);
// Chaining (sequential)
const order = await orderClient.create(data);
const payment = await paymentClient.process(order.id);
Resources
- Traefik Documentation - Official Traefik docs
- API Gateway Pattern - Gateway patterns
- Service Mesh - Istio service mesh
- Detailed Code Examples
- Middleware Patterns - Middleware patterns
- Resilience Patterns - Circuit breaker patterns