Testar grátis
8 min leitura Guide 855 of 877

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

Soluções Relacionadas