Rate Limiting em TypeScript: guia completo sobre ferramentas e implementação
Rate limiting (limitação de velocidade de requisições) é uma das principais técnicas para proteger aplicações web e APIs contra abusos, ataques DDoS e sobrecarga excessiva. Em TypeScript, graças à tipagem forte e aos recursos modernos, a implementação de rate limiting se torna especialmente elegante e confiável. Neste artigo, vamos explorar as melhores bibliotecas, algoritmos e exemplos de código para TypeScript.
Por que o Rate Limiting é necessário?
Sem a limitação de velocidade de requisições, sua aplicação pode enfrentar:
- Sobrecarga do servidor — um único cliente pode enviar milhares de requisições por segundo
- Ataques de força bruta — tentativas de adivinhar senhas ou tokens
- Perdas financeiras — se cada requisição consumir recursos pagos (ex.: API da OpenAI)
- Distribuição desigual de recursos — um usuário pode consumir toda a largura de banda
Bibliotecas populares para Rate Limiting em TypeScript
1. bottleneck — limitador universal
Uma das bibliotecas mais populares para rate limiting em JavaScript/TypeScript. Suporta tanto a limitação por número de requisições por segundo/minuto quanto o "hanging" (acúmulo) de requisições em fila.
import Bottleneck from 'bottleneck';
const limiter = new Bottleneck({ maxConcurrent: 2, // máximo de 2 requisições simultâneas minTime: 1000, // mínimo de 1 segundo entre requisições reservoir: 10, // limite total por período reservoirRefreshAmount: 10, reservoirRefreshInterval: 60 * 1000 // renovação a cada minuto});
async function fetchData(url: string): Promise<any> { return limiter.schedule(() => fetch(url));}
// Usoconst users = await Promise.all([ fetchData('/api/users/1'), fetchData('/api/users/2'), fetchData('/api/users/3'), // esta requisição aguardará]);2. express-rate-limit — para Express.js
Solução padrão para limitar requisições em aplicações Express. Funciona muito bem com TypeScript.
import express from 'express';import rateLimit from 'express-rate-limit';
const app = express();
const apiLimiter = rateLimit({ windowMs: 15 * 60 * 1000, // 15 minutos max: 100, // máximo de 100 requisições standardHeaders: true, // retornar cabeçalhos RateLimit-* legacyHeaders: false, message: { status: 429, message: 'Muitas requisições, tente novamente mais tarde' }});
app.use('/api/', apiLimiter);
app.listen(3000);3. rate-limiter-flexible — solução flexível para Redis e memória integrada
Biblioteca com suporte a diversos armazenamentos (Redis, Memory, MongoDB, Postgres) e algoritmos (Token Bucket, Sliding Window).
import { RateLimiterMemory } from 'rate-limiter-flexible';
const rateLimiter = new RateLimiterMemory({ points: 5, // 5 requisições duration: 1, // por 1 segundo});
async function checkRateLimit(key: string): Promise<boolean> { try { await rateLimiter.consume(key); return true; // requisição permitida } catch (error) { return false; // limite excedido }}
// Exemplo de uso no Expressapp.post('/api/login', async (req, res) => { const allowed = await checkRateLimit(req.ip); if (!allowed) { return res.status(429).json({ error: 'Too Many Requests' }); } // processamento do login...});Algoritmos de Rate Limiting
- Token Bucket — um "balde" com tokens que são reabastecidos a uma taxa constante. Cada requisição consome um token. Permite picos temporários.
- Sliding Window — janela de tempo deslizante (ex.: 1 minuto). Considera requisições não em intervalos fixos, mas nos últ