Limitação de requisições em JavaScript: como não deixar a API cair

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course

Rate limiting e throttling em JavaScript: Proteção e Performance

\n\n

Você já se perguntou por que, depois de alguns cliques rápidos no botão "Enviar", seu serviço favorito de repente para de responder? Ou por que alguns sites pedem para você "aguardar 30 segundos" antes de reenviar um formulário? A resposta está em dois mecanismos poderosos que salvam o backend da sobrecarga e os usuários de "bugs": rate limiting e throttling.

\n\n

Neste artigo, vamos explorar como aplicar essas técnicas em JavaScript puro e Node.js. Você aprenderá a diferença entre throttle e debounce, como escrever um rate limiter simples para APIs e por que seu site ficará mais rápido. Vamos lá!

\n\n

O que é rate limiting e para que serve?

\n\n

Rate limiting (limitação de taxa de requisições) é um mecanismo de proteção que limita o número de requisições de um cliente (ou endereço IP) em um determinado período de tempo. Imagine uma catraca: um carro pode passar, mas apenas uma vez a cada 10 segundos.

\n\n

Onde isso é aplicado?

\n
    \n
  • Proteção de APIs contra ataques DDoS e spam.
  • \n
  • Prevenção de sobrecarga do servidor com requisições em massa.
  • \n
  • Controle de uso de recursos em APIs pagas (ex.: 100 requisições por hora).
  • \n
  • Proteção contra erros de "loop infinito" no cliente.
  • \n
\n\n

Ao contrário do throttling, que suaviza o fluxo de requisições, o rate limiting é uma barreira rígida: "Pare, você excedeu o limite".

\n\n

Throttling vs Debounce: a principal diferença

\n\n

Frequentemente, throttling e debounce são confundidos. Vamos esclarecer isso de uma vez.

\n\n
    \n
  • Throttle — garante que uma função seja chamada no máximo uma vez a cada N milissegundos. Imagine uma torneira: você a abre e a água flui a uma velocidade constante, mesmo que você gire o manípulo mais rápido.
  • \n
  • Debounce — adia a chamada de uma função até que N milissegundos tenham passado desde o último evento. Ideal para pesquisa com autocompletar: enquanto o usuário digita, a requisição não é enviada.
  • \n
\n\n

No contexto de rate limiting, estamos interessados especificamente no throttle — queremos controlar a frequência, não adiar as requisições.

\n\n

Rate limiter simples em JavaScript

\n\n

Vamos escrever nossa própria implementação de rate limiter em Node.js. Ela armazenará o horário da última requisição de cada usuário e bloqueará acessos muito frequentes.

\n\n
class RateLimiter {\n  constructor(limit, windowMs) {\n    this.limit = limit;          // Máximo de requisições\n    this.windowMs = windowMs;    // Janela de tempo em ms\n    this.requests = new Map();   // Armazenamento: userId -> [timestamps]\n  }\n\n  allow(userId) {\n    const now = Date.now();\n    const userRequests = this.requests.get(userId) || [];\n    \n    // Remove registros antigos\n    const recentRequests = userRequests.filter(\n      ts => now - ts < this.windowMs\n    );\n    \n    if (recentRequests.length >= this.limit) {\n      console.log(`Rate limit excedido para ${userId}`);\n      return false;\n    }\n    \n    recentRequests.push(now);\n    this.requests.set(userId, recentRequests);\n    return true;\n  }\n}\n\n// Uso\nconst limiter = new RateLimiter(5, 60000); // 5 requisições por minuto\n\n// Simulação de requisições\nfor (let i = 0; i < 10; i++) {\n  setTimeout(() => {\n    const allowed = limiter.allow('user123');\n    console.log(`Requisição ${i+1}: ${allowed ? '✅ Permitida' : '❌ Bloqueada'}`);\n  }, i * 2000); // A cada 2 segundos\n}
\n\n

Este código é ótimo para fins educacionais, mas em produção é melhor usar soluções prontas (por exemplo, express-rate-limit para Express ou rate-limiter-flexible).

\n\n

Throttling no cliente: proteção contra cliques rápidos

\n\n

Frequentemente, o problema surge no lado do cliente: o usuário clica várias vezes no botão "Enviar" e as requisições são enviadas em paralelo. R

Blogs

Book Recommendations