Limitación de Tasa en TypeScript: guía completa sobre herramientas e implementación
La limitación de tasa (rate limiting) es una de las técnicas clave para proteger aplicaciones web y API contra abusos, ataques DDoS y carga excesiva. En TypeScript, gracias al tipado estricto y las capacidades modernas, la implementación de la limitación de tasa se vuelve especialmente elegante y confiable. En este artículo, analizaremos las mejores bibliotecas, algoritmos y ejemplos de código para TypeScript.
¿Por qué es necesaria la Limitación de Tasa?
Sin limitación de velocidad de solicitudes, su aplicación puede enfrentarse a:
- Sobrecarga del servidor — un cliente puede enviar miles de solicitudes por segundo
- Ataques de fuerza bruta — adivinación de contraseñas o tokens
- Pérdidas financieras — si cada solicitud requiere recursos pagados (por ejemplo, API de OpenAI)
- Distribución desigual de recursos — un usuario puede acaparar todo el ancho de banda
Bibliotecas populares para Limitación de Tasa en TypeScript
1. bottleneck — limitador universal
Una de las bibliotecas más populares para limitación de tasa en JavaScript/TypeScript. Admite tanto la limitación por cantidad de solicitudes por segundo/minuto como la acumulación ("hanging") de solicitudes en cola.
import Bottleneck from 'bottleneck';
const limiter = new Bottleneck({ maxConcurrent: 2, // máximo 2 solicitudes simultáneas minTime: 1000, // mínimo 1 segundo entre solicitudes reservoir: 10, // límite total por período reservoirRefreshAmount: 10, reservoirRefreshInterval: 60 * 1000 // renovación 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 solicitud esperará]);2. express-rate-limit — para Express.js
Solución estándar para limitar solicitudes en aplicaciones Express. Funciona muy bien con 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 100 solicitudes standardHeaders: true, // devolver cabeceras RateLimit-* legacyHeaders: false, message: { status: 429, message: 'Demasiadas solicitudes, intente más tarde' }});
app.use('/api/', apiLimiter);
app.listen(3000);3. rate-limiter-flexible — solución flexible para Redis y memoria integrada
Biblioteca con soporte para varios almacenes (Redis, Memory, MongoDB, Postgres) y algoritmos (Token Bucket, Sliding Window).
import { RateLimiterMemory } from 'rate-limiter-flexible';
const rateLimiter = new RateLimiterMemory({ points: 5, // 5 solicitudes duration: 1, // por 1 segundo});
async function checkRateLimit(key: string): Promise<boolean> { try { await rateLimiter.consume(key); return true; // solicitud permitida } catch (error) { return false; // límite excedido }}
// Ejemplo de uso en Expressapp.post('/api/login', async (req, res) => { const allowed = await checkRateLimit(req.ip); if (!allowed) { return res.status(429).json({ error: 'Too Many Requests' }); } // procesamiento del inicio de sesión...});Algoritmos de Limitación de Tasa
- Token Bucket — un "cubo" con tokens que se reponen a una velocidad constante. Cada solicitud consume un token. Permite ráfagas temporales.
- Sliding Window — ventana de tiempo deslizante (por ejemplo, 1 minuto). Considera las solicitudes no en intervalos fijos, sino en los últimos