Rate Limiting в TypeScript: библиотеки, инструменты и примеры реализации

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Rate Limiting в TypeScript: полное руководство по инструментам и реализации

Rate limiting (ограничение скорости запросов) — одна из ключевых техник защиты веб-приложений и API от злоупотреблений, DDoS-атак и чрезмерной нагрузки. В TypeScript, благодаря строгой типизации и современным возможностям, реализация rate limiting становится особенно элегантной и надёжной. В этой статье мы разберём лучшие библиотеки, алгоритмы и примеры кода для TypeScript.

Зачем нужен Rate Limiting?

Без ограничения скорости запросов ваше приложение может столкнуться с:

  • Перегрузкой сервера — один клиент может отправить тысячи запросов в секунду
  • Брутфорс-атаками — подбор паролей или токенов
  • Финансовыми потерями — если каждый запрос требует платных ресурсов (например, API OpenAI)
  • Неравномерным распределением ресурсов — один пользователь может забрать всю пропускную способность

Популярные библиотеки для Rate Limiting в TypeScript

1. bottleneck — универсальный ограничитель

Одна из самых популярных библиотек для rate limiting в JavaScript/TypeScript. Поддерживает как ограничение по количеству запросов в секунду/минуту, так и "hanging" (накопление) запросов в очереди.

import Bottleneck from 'bottleneck';

const limiter = new Bottleneck({
  maxConcurrent: 2,        // максимум 2 одновременных запроса
  minTime: 1000,           // минимум 1 секунда между запросами
  reservoir: 10,           // общий лимит на период
  reservoirRefreshAmount: 10,
  reservoirRefreshInterval: 60 * 1000 // обновление каждую минуту
});

async function fetchData(url: string): Promise<any> {
  return limiter.schedule(() => fetch(url));
}

// Использование
const users = await Promise.all([
  fetchData('/api/users/1'),
  fetchData('/api/users/2'),
  fetchData('/api/users/3'), // этот запрос будет ждать
]);

2. express-rate-limit — для Express.js

Стандартное решение для ограничения запросов в Express-приложениях. Отлично работает с TypeScript.

import express from 'express';
import rateLimit from 'express-rate-limit';

const app = express();

const apiLimiter = rateLimit({
  windowMs: 15 * 60 * 1000, // 15 минут
  max: 100,                 // максимум 100 запросов
  standardHeaders: true,    // возвращать заголовки RateLimit-*
  legacyHeaders: false,
  message: {
    status: 429,
    message: 'Слишком много запросов, попробуйте позже'
  }
});

app.use('/api/', apiLimiter);

app.listen(3000);

3. rate-limiter-flexible — гибкое решение для Redis и встроенной памяти

Библиотека с поддержкой различных хранилищ (Redis, Memory, MongoDB, Postgres) и алгоритмов (Token Bucket, Sliding Window).

import { RateLimiterMemory } from 'rate-limiter-flexible';

const rateLimiter = new RateLimiterMemory({
  points: 5,        // 5 запросов
  duration: 1,      // за 1 секунду
});

async function checkRateLimit(key: string): Promise<boolean> {
  try {
    await rateLimiter.consume(key);
    return true; // запрос разрешён
  } catch (error) {
    return false; // превышен лимит
  }
}

// Пример использования в Express
app.post('/api/login', async (req, res) => {
  const allowed = await checkRateLimit(req.ip);
  if (!allowed) {
    return res.status(429).json({ error: 'Too Many Requests' });
  }
  // обработка логина...
});

Алгоритмы Rate Limiting

  • Token Bucket — "ведро" с токенами, которые пополняются с постоянной скоростью. Каждый запрос потребляет один токен. Позволяет кратковременные всплески.
  • Sliding Window — скользящее окно времени (например, 1 минута). Учитывает запросы не за фиксированные интервалы, а за последние N секунд. Более точный.
  • Fixed Window — фиксированные временные окна (например, каждый час). Простой, но может пропускать "краевые" всплески.
  • Leaky Bucket — запросы обрабатываются с постоянной скоростью, избыток отбрасывается или ставится в очередь.

Продвинутый пример: кастомный декоратор для Rate Limiting

В TypeScript можно создать элегантный декоратор для ограничения вызова методов:

function RateLimit(maxRequests: number, windowMs: number) {
  const store = new Map<string, { count: number; resetTime:                    

Рекомендаций