Rate limiting e proteção contra abuso
Sem limite de requisição, um único cliente mal-intencionado (ou um bug num script) consegue derrubar a API pra todo mundo.
Praticamente toda API pública limita quantas requisições um mesmo cliente pode fazer num intervalo de tempo. Não é paranoia: sem limite, um script com bug rodando em loop, um scraper agressivo, ou uma tentativa de força bruta contra login conseguem consumir toda a capacidade do servidor — prejudicando todos os outros usuários legítimos ao mesmo tempo.
Token bucket — a ideia mais comum por trás do rate limit
Um jeito simples (e muito usado) de implementar limite de requisição é o token bucket: existe um "balde" com capacidade fixa de tokens; cada requisição consome um token; o balde recarrega a uma taxa constante. Sem token disponível, a requisição é recusada — mas o balde permite uma rajada momentânea de requisições (até a capacidade do balde), não só uma taxa média rígida.
capacidade = 10 // até 10 requisições em rajada
tokens = 10
taxa_recarga = 1/segundo // 1 token novo a cada segundo
a cada requisição recebida:
se tokens > 0:
tokens = tokens - 1
processa a requisição normalmente
senão:
responde 429 Too Many Requests429 Too Many Requests — o status pensado pra isso
HTTP/1.1 429 Too Many Requests
Retry-After: 30
Content-Type: application/json
{"error": "Limite de requisições excedido. Tente novamente em 30 segundos."}O header Retry-After diz explicitamente ao cliente quanto tempo esperar antes de tentar de novo — evitando que ele fique tentando imediatamente em loop, o que só pioraria a situação.
Onde aplicar o limite
limit_req_zone $binary_remote_addr zone=api:10m rate=5r/s;
server {
location /api/ {
limit_req zone=api burst=10 nodelay;
proxy_pass http://backend;
}
}O limite normalmente é aplicado por cliente (IP, chave de API, ou usuário autenticado), não de forma global — senão um único cliente abusivo derrubaria a cota de todo mundo. Pode viver no proxy reverso (como no exemplo acima), na própria aplicação, ou num serviço dedicado com contador compartilhado (Redis costuma ser a escolha, já que vários servidores atrás de um load balancer precisam enxergar a mesma contagem).
Exercício
Por que um endpoint de login geralmente precisa de um limite de requisição bem mais rígido do que um endpoint público de leitura, tipo listar produtos de uma loja?