Comment implémenter la limitation du taux d'API ?

Ashley Innocent

Ashley Innocent

13 March 2026

Comment implémenter la limitation du taux d'API ?

Apidog pour les entreprises

Déploiement sur site

SSO & RBAC

Conforme SOC 2

Découvrir Apidog Enterprise

En bref

Implémentez la limitation de débit d'API en utilisant les algorithmes de seau à jetons (token bucket) ou de fenêtre glissante (sliding window). Retournez les en-têtes standard IETF de limitation de débit (RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset) et le code 429 Too Many Requests lorsque les limites sont dépassées. La Modern PetstoreAPI implémente la limitation de débit avec des quotas par utilisateur et des réponses d'erreur claires.

Introduction

Un client effectue 10 000 requêtes à votre API en une minute. Votre base de données plante. Vos alertes de surveillance se déclenchent. Vos autres clients ne peuvent plus accéder à l'API. Vous êtes sous attaque—ou peut-être simplement confronté à un client buggé en boucle de réessai.

La limitation de débit (rate limiting) empêche cela. Elle plafonne le nombre de requêtes qu'un client peut effectuer dans une fenêtre de temps donnée. Lorsqu'il dépasse la limite, vous renvoyez 429 Too Many Requests. Le client ralentit ses requêtes, et votre API reste saine.

L'ancienne Swagger Petstore n'implémente pas du tout la limitation de débit. Modern PetstoreAPI implémente la limitation de débit avec des en-têtes IETF standard, des quotas par utilisateur et des réponses d'erreur claires.

💡
Si vous construisez ou testez des API REST, Apidog vous aide à tester le comportement de la limitation de débit, à valider les en-têtes de limitation de débit et à vous assurer que votre API gère correctement les requêtes excessives. Vous pouvez simuler des scénarios à volume élevé et vérifier les réponses de limitation de débit.
button

Dans ce guide, vous apprendrez les algorithmes de limitation de débit, les en-têtes standard et comment Modern PetstoreAPI implémente correctement la limitation de débit.

Pourquoi les API ont besoin de la limitation de débit

La limitation de débit protège votre API contre les abus et assure une utilisation équitable.

Protection contre les abus

1. Attaques par déni de service (DoS)

Un attaquant inonde votre API de requêtes pour la rendre indisponible. La limitation de débit plafonne leur impact.

2. Attaques par bourrage d'identifiants (Credential stuffing)

Les attaquants tentent des milliers de combinaisons nom d'utilisateur/mot de passe. La limitation de débit les ralentit.

3. Extraction de données (Data scraping)

Les bots extraient l'intégralité de votre jeu de données. La limitation de débit rend l'extraction irréalisable.

4. Contrôle des coûts

Si votre API appelle des services coûteux (modèles d'IA, API tierces), la limitation de débit empêche les coûts incontrôlés.

Utilisation équitable

1. Empêcher un client de monopoliser les ressources

Sans limitation de débit, un client effectuant 1000 requêtes/seconde peut priver les autres clients de ressources.

2. Performance prévisible

La limitation de débit assure des temps de réponse constants pour tous les clients.

3. Accès par niveaux

Niveau gratuit : 100 requêtes/heure. Niveau payant : 10 000 requêtes/heure. La limitation de débit applique ces niveaux.

Avantages opérationnels

1. Planification de la capacité

Vous connaissez la charge maximale que votre API supportera.

2. Prévisibilité des coûts

Les limites de débit plafonnent les coûts d'infrastructure.

3. Dégradation en douceur

En cas de charge, la limitation de débit empêche les défaillances en cascade.

Algorithmes de limitation de débit

Différents algorithmes ont des compromis différents.

1. Fenêtre fixe (Fixed Window)

Compte les requêtes dans des fenêtres de temps fixes.

Fonctionnement :

Fenêtre 1 (00:00-00:59) : 100 requêtes autorisées
Fenêtre 2 (01:00-01:59) : 100 requêtes autorisées

Implémentation :

def is_allowed(user_id):
    current_minute = get_current_minute()
    key = f"rate_limit:{user_id}:{current_minute}"
    count = redis.incr(key)
    redis.expire(key, 60)
    return count <= 100

Avantages :

Inconvénients :

2. Fenêtre glissante (Sliding Window)

Compte les requêtes dans une fenêtre de temps glissante.

Fonctionnement :

À 01:30, compte les requêtes de 00:30 à 01:30 (les 60 dernières minutes).

Implémentation :

def is_allowed(user_id):
    now = time.time()
    window_start = now - 3600  # 1 heure auparavant
    key = f"rate_limit:{user_id}"

    # Supprimer les anciennes requêtes
    redis.zremrangebyscore(key, 0, window_start)

    # Compter les requêtes dans la fenêtre
    count = redis.zcard(key)

    if count < 100:
        redis.zadd(key, {now: now})
        redis.expire(key, 3600)
        return True
    return False

Avantages :

Inconvénients :

3. Seau à jetons (Token Bucket)

Les jetons sont ajoutés à un seau à un rythme fixe. Chaque requête consomme un jeton.

Fonctionnement :

Capacité du seau : 100 jetons
Taux de remplissage : 10 jetons/seconde
Requête : consomme 1 jeton

Implémentation :

def is_allowed(user_id):
    now = time.time()
    key = f"rate_limit:{user_id}"

    # Obtenir l'état actuel
    data = redis.hgetall(key)
    tokens = float(data.get('tokens', 100))
    last_refill = float(data.get('last_refill', now))

    # Recharger les jetons
    elapsed = now - last_refill
    tokens = min(100, tokens + elapsed * 10)  # 10 jetons/sec

    if tokens >= 1:
        tokens -= 1
        redis.hset(key, 'tokens', tokens)
        redis.hset(key, 'last_refill', now)
        redis.expire(key, 3600)
        return True
    return False

Avantages :

Inconvénients :

4. Seau percé (Leaky Bucket)

Les requêtes sont ajoutées à une file d'attente et traitées à un rythme fixe.

Fonctionnement :

Capacité de la file d'attente : 100 requêtes
Taux de traitement : 10 requêtes/seconde

Avantages :

Inconvénients :

Quel algorithme utiliser ?

Pour la plupart des API : Le seau à jetons (Token Bucket)

C'est le standard de l'industrie, il permet des rafales raisonnables et offre une limitation de débit fluide.

Modern PetstoreAPI utilise le seau à jetons avec des quotas par utilisateur.

En-têtes de limitation de débit standard

Utilisez les en-têtes standard IETF (draft-ietf-httpapi-ratelimit-headers).

En-têtes standard

RateLimit-Limit : Nombre maximum de requêtes autorisées dans la fenêtre de temps

RateLimit-Limit: 100

RateLimit-Remaining : Requêtes restantes dans la fenêtre actuelle

RateLimit-Remaining: 45

RateLimit-Reset : Secondes avant la réinitialisation de la limite de débit

RateLimit-Reset: 3600

Exemple de réponse

GET /pets
200 OK
RateLimit-Limit: 100
RateLimit-Remaining: 99
RateLimit-Reset: 3600

{
  "data": [...]
}

En-têtes obsolètes (dépréciés)

De nombreuses API utilisent des en-têtes non standard :

X-RateLimit-Limit: 100
X-RateLimit-Remaining: 99
X-RateLimit-Reset: 1710331200

Ne les utilisez pas. Le préfixe X- est déprécié, et le format n'est pas standardisé.

Comment Modern PetstoreAPI implémente la limitation de débit

Modern PetstoreAPI implémente la limitation de débit de type seau à jetons avec des en-têtes standard.

Limites de débit par niveau

Niveau gratuit :

Niveau Pro :

Niveau Entreprise :

Implémentation

Requête réussie :

GET /v1/pets
200 OK
RateLimit-Limit: 100
RateLimit-Remaining: 99
RateLimit-Reset: 3540

{
  "data": [...]
}

Limite de débit dépassée :

GET /v1/pets
429 Too Many Requests
Content-Type: application/problem+json
RateLimit-Limit: 100
RateLimit-Remaining: 0
RateLimit-Reset: 120
Retry-After: 120

{
  "type": "https://petstoreapi.com/errors/rate-limit-exceeded",
  "title": "Limite de débit dépassée",
  "status": 429,
  "detail": "Vous avez dépassé la limite de débit de 100 requêtes par heure",
  "instance": "/v1/pets",
  "retryAfter": 120,
  "limit": 100,
  "window": "1h"
}

Par utilisateur vs par IP

Par utilisateur (requêtes authentifiées) :

Limitation de débit par ID utilisateur ou clé API. Plus précis et équitable.

user_id = get_authenticated_user()
is_allowed(user_id)

Par IP (requêtes non authentifiées) :

Limitation de débit par adresse IP. Moins précis (IP partagées, VPN) mais mieux que rien.

ip_address = request.remote_addr
is_allowed(ip_address)

Modern PetstoreAPI utilise la limitation de débit par utilisateur pour les requêtes authentifiées et par IP pour les points de terminaison publics.

Format de réponse de limitation de débit

Lorsque les limites de débit sont dépassées, retournez 429 avec le format d'erreur RFC 9457.

Structure de la réponse

{
  "type": "https://petstoreapi.com/errors/rate-limit-exceeded",
  "title": "Limite de débit dépassée",
  "status": 429,
  "detail": "Vous avez dépassé votre limite de débit. Veuillez réessayer plus tard.",
  "instance": "/v1/pets",
  "retryAfter": 120,
  "limit": 100,
  "remaining": 0,
  "reset": 120,
  "window": "1h"
}

En-têtes

429 Too Many Requests
RateLimit-Limit: 100
RateLimit-Remaining: 0
RateLimit-Reset: 120
Retry-After: 120

Retry-After : Indique aux clients quand réessayer (en secondes).

Tester les limites de débit avec Apidog

Apidog vous aide à tester le comportement de la limitation de débit.

Scénarios de test

1. Utilisation normale :

Envoyer 50 requêtes → Toutes réussissent
Vérifier que RateLimit-Remaining diminue

2. Dépasser la limite :

Envoyer 101 requêtes → La 101e renvoie 429
Vérifier le format de la réponse d'erreur
Vérifier l'en-tête Retry-After

3. Comportement de réinitialisation :

Dépasser la limite → Attendre la réinitialisation → Vérifier que la limite est rétablie

4. Différents niveaux :

Tester le niveau gratuit (100/heure)
Tester le niveau pro (10 000/heure)
Vérifier que les limites sont correctement appliquées

Exemple de test Apidog

// Tester les en-têtes de limitation de débit
pm.test("Les en-têtes de limitation de débit sont présents", () => {
  pm.response.to.have.header("RateLimit-Limit");
  pm.response.to.have.header("RateLimit-Remaining");
  pm.response.to.have.header("RateLimit-Reset");
});

// Tester la limite de débit dépassée
pm.test("Renvoie 429 lorsque la limite est dépassée", () => {
  // Effectuer 101 requêtes
  for (let i = 0; i < 101; i++) {
    pm.sendRequest("GET /v1/pets");
  }
  pm.response.to.have.status(429);
});

Bonnes pratiques de limitation de débit

1. Utiliser des en-têtes standard

Utilisez les en-têtes standard IETF, et non les en-têtes X- personnalisés.

2. Retourner 429, pas 403

429 signifie "trop de requêtes". 403 signifie "interdit". Ne les confondez pas.

3. Inclure Retry-After

Indiquez aux clients quand ils peuvent réessayer.

4. Documenter vos limites

Rendez les limites de débit visibles dans la documentation.

5. Fournir différents niveaux

Niveau gratuit : limites faibles. Niveau payant : limites plus élevées.

6. Limiter le débit par utilisateur, pas par IP

Les limites par utilisateur sont plus précises et équitables.

7. Autoriser les rafales

Le seau à jetons permet des rafales raisonnables sans pénaliser l'utilisation normale.

8. Surveiller les dépassements de limites de débit

Suivez la fréquence à laquelle les clients atteignent les limites de débit. Des taux élevés indiquent des problèmes.

9. Fournir un point de terminaison d'état de la limite de débit

GET /v1/rate-limit
200 OK
{
  "limit": 100,
  "remaining": 45,
  "reset": 3540
}

10. Tester la limitation de débit

Utilisez Apidog pour tester le comportement de la limitation de débit avant le déploiement.

Conclusion

La limitation de débit protège votre API contre les abus et assure une utilisation équitable. Utilisez l'algorithme du seau à jetons avec les en-têtes standard IETF (RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset). Retournez 429 Too Many Requests avec le format d'erreur RFC 9457 lorsque les limites sont dépassées.

Modern PetstoreAPI implémente correctement la limitation de débit avec des quotas par utilisateur, des en-têtes standard et des réponses d'erreur claires. Consultez la documentation pour plus de détails sur l'implémentation.

Testez votre limitation de débit avec Apidog pour vous assurer qu'elle fonctionne correctement sous charge et gère correctement les cas limites.

button

FAQ

Quelles limites de débit devrais-je définir ?

Commencez de manière conservatrice : 100 requêtes/heure pour le niveau gratuit, 10 000/heure pour le niveau payant. Ajustez en fonction des modèles d'utilisation et de la capacité de l'infrastructure.

Devrais-je limiter le débit par IP ou par utilisateur ?

Limitez le débit par utilisateur (clé API) pour les requêtes authentifiées. N'utilisez la limitation de débit par IP que pour les points de terminaison publics.

Que se passe-t-il si un client dépasse la limite de débit ?

Retournez 429 Too Many Requests avec l'en-tête Retry-After. Ne bloquez pas le client définitivement—laissez-le réessayer une fois la fenêtre réinitialisée.

Comment gérer les limites de débit pour les webhooks ?

Les webhooks sont de serveur à serveur, donc les limites de débit devraient être plus élevées. Envisagez des limites distinctes pour les webhooks et les appels API.

Devrais-je limiter le débit des services internes ?

Oui, mais avec des limites beaucoup plus élevées. La limitation de débit prévient les défaillances en cascade même dans les systèmes internes.

Comment tester la limitation de débit ?

Utilisez Apidog pour envoyer plusieurs requêtes et vérifier les réponses 429, les en-têtes de limitation de débit et le comportement de réinitialisation.

Que faire si mon API est derrière un CDN ?

La mise en cache CDN réduit la charge, mais vous avez toujours besoin de la limitation de débit pour les échecs de cache et les requêtes POST/PUT/DELETE.

Comment implémenter la limitation de débit sur plusieurs serveurs ?

Utilisez un magasin de données partagé (Redis, Memcached) pour suivre les limites de débit sur tous les serveurs. N'utilisez pas la mémoire locale—cela ne fonctionnera pas dans les systèmes distribués.

Pratiquez le Design-first d'API dans Apidog

Découvrez une manière plus simple de créer et utiliser des API

Comment implémenter la limitation du taux d'API ?