TypeScript sous le capot : Rate limiting et throttling sans douleur

Formateur Python en ligne pour débutants

Apprenez Python facilement sans surcharge théorique. Résolvez des tâches pratiques avec vérification automatique et écrivez du code directement dans le navigateur.

Start Course

Comment empêcher votre API de s'effondrer sous un déluge de requêtes

\n\n

Imaginez : vous avez lancé un super service, écrit un backend en TypeScript, et là — bam ! — un utilisateur « gentil » lance un script qui bombarde votre endpoint avec des milliers de requêtes par seconde. Le serveur tombe, la base de données s'étouffe, et les utilisateurs honnêtes voient une erreur 502. Ça vous parle ?

\n\n

Dans le monde du développement web, le rate limiting (limitation du débit des requêtes) et le throttling (étranglement) ne sont pas que des mots à la mode, mais une bouée de sauvetage pour votre API. Aujourd'hui, nous allons voir comment implémenter ces mécanismes en TypeScript sans vous casser la tête. C'est parti !

\n\n

Rate limiting vs Throttling : quelle est la différence ?

\n\n

Avant d'écrire du code, clarifions bien les concepts. Beaucoup les confondent, mais la différence est fondamentale.

\n\n
    \n
  • Rate limiting — c'est une limite stricte : « Pas plus de 100 requêtes par minute depuis une même IP ». Vous dépassez ? Vous recevez un 429 Too Many Requests et un blocage jusqu'à la fin de la fenêtre. Cela fonctionne au niveau de la passerelle API.
  • \n
  • Throttling — c'est une régulation en douceur : « Vous pouvez faire des requêtes, mais pas plus d'une par seconde ». Les autres requêtes sont soit mises en file d'attente, soit ignorées, mais l'utilisateur n'est pas bloqué.
  • \n
\n\n

Une analogie simple : le rate limiting, c'est le tourniquet du métro (vous passez votre carte, vous passez ; sinon, vous attendez), tandis que le throttling, c'est l'agent de régulation à un carrefour (les voitures avancent, mais à intervalles réguliers).

\n\n

Quand en a-t-on besoin ? Scénarios réels

\n\n

Vous allez dire : « J'ai un petit site, pourquoi en aurais-je besoin ? » Voici pourquoi :

\n\n
    \n
  • Protection contre les DDoS et le brute force — les attaquants ne pourront pas essayer des mots de passe en masse ou faire tomber le serveur.
  • \n
  • Économie de ressources — les API payantes (comme OpenAI) facturent chaque appel. En limitant les clients, vous sauvez votre budget.
  • \n
  • Répartition équitable de la charge — un utilisateur « bruyant » n'écrasera pas tous les autres.
  • \n
  • Respect des SLA — si vous promettez un uptime de 99,9 %, vous ne pouvez pas vous passer de limitations.
  • \n
\n\n

Écrire un rate limiting en TypeScript : un début simple

\n\n

Commençons par un exemple de base — un in-memory rate limiter basé sur une fenêtre fixe (Fixed Window). Il stocke les compteurs de requêtes directement dans la mémoire de l'application.

\n\n
// rateLimiter.ts\nimport { Request, Response, NextFunction } from 'express';\n\ninterface RateLimitEntry {\n    count: number;\n    resetTime: number;\n}\n\nclass InMemoryRateLimiter {\n    private store: Map<string, RateLimitEntry> = new Map();\n    private windowMs: number;\n    private maxRequests: number;\n\n    constructor(windowMs: number, maxRequests: number) {\n        this.windowMs = windowMs;\n        this.maxRequests = maxRequests;\n    }\n\n    public middleware() {\n        return (req: Request, res: Response, next: NextFunction): void => {\n            const key = req.ip || 'unknown';\n            const now = Date.now();\n            let entry = this.store.get(key);\n\n            if (!entry || now > entry.resetTime) {\n                // Nouvelle fenêtre\n                entry = { count: 0, resetTime: now + this.windowMs };\n                this.store.set(key, entry);\n            }\n\n            entry.count++;\n\n            if (entry.count > this.maxRequests) {\n                res.status(429).json({\n                    error: 'Too Many Requests',\n                    retryAfter: Math.ceil((entry.resetTime - now) / 1000)\n                });\n                return;\n            }\n\n            // Transmission des informations de limite dans les en-têtes\n            res.setHeader('X-RateLimit-Limit', this.maxRequests);\n            res.setHeader('X-RateLimit-Remaining', this.maxRequests - entry.count);\n            res.setHeader('X-RateLimit-Reset', Math.ceil(entry.resetTime / 1000));\n\n            next();\n        };\n    }\n\n    // Nettoyage des anciennes entrées (pour éviter les fuites mémoire)\n    public cleanup(): void {\                

Blogs

Book Recommendations