Les API sont un excellent moyen pour les applications logicielles de communiquer entre elles. Elles permettent aux applications logicielles d’interagir et de partager des ressources ou des privilèges.

Aujourd’hui, de nombreuses entreprises B2B proposent leurs services via des API qui peuvent être utilisées par des applications conçues dans n’importe quel langage de programmation et n’importe quel framework. Cependant, cela les rend vulnérables aux attaques DoS et DDoS et peut également conduire à une distribution inégale de la bande passante entre les utilisateurs. Pour résoudre ces problèmes, une technique connue sous le nom de « API rate limiting » est mise en œuvre. L’idée est simple : vous limitez le nombre de requêtes que les utilisateurs peuvent adresser à votre API.

Dans ce guide, vous apprendrez ce qu’est la limitation du débit de l’API, les différentes façons dont elle peut être mise en œuvre, ainsi que quelques bonnes pratiques et exemples à retenir lors de la mise en place de la limitation du débit de l’API.

Qu’est-ce que la limitation du débit de l’API ?

En termes simples, la limitation du débit de l’API consiste à fixer un seuil ou une limite au nombre de fois qu’une API peut être consultée par ses utilisateurs. Les limites peuvent être fixées de plusieurs manières.

1. Limites basées sur l’utilisateur

L’une des façons de fixer une limite de débit consiste à réduire le nombre de fois qu’un utilisateur donné peut accéder à l’API dans un laps de temps donné. Pour cela, vous pouvez compter le nombre de requêtes effectuées à l’aide de la même clé API ou de la même adresse IP ; lorsqu’un seuil est atteint, les requêtes supplémentaires sont limitées ou refusées.

2. Limites basées sur la localisation

Dans de nombreux cas, les développeurs souhaitent répartir la bande passante disponible pour leur API de manière égale entre certains emplacements géographiques.

Le récent service de prévisualisation ChatGPT est un bon exemple de limitation de débit basée sur la localisation, car il a commencé à limiter les requêtes en fonction de la localisation des utilisateurs sur la version gratuite du service, une fois que la version payante a été déployée. C’était logique puisque la version gratuite était censée être utilisée par des personnes du monde entier afin de générer un bon échantillon de données d’utilisation pour le service.

3. Limites basées sur le serveur

La limitation de débit basée sur le serveur est une limite de débit interne mise en œuvre du côté du serveur pour assurer une distribution équitable des ressources du serveur telles que l’unité centrale, la mémoire, l’espace disque, etc. Il s’agit de mettre en place une limite sur chaque serveur d’un déploiement.

Lorsqu’un serveur atteint sa limite, les autres requêtes entrantes sont acheminées vers un autre serveur disposant d’une capacité disponible. Si tous les serveurs ont atteint leur capacité, l’utilisateur reçoit une réponse 429 Too Many Requests. Il est important de noter que les limites de débit basées sur les serveurs sont appliquées à tous les clients, indépendamment de leur situation géographique, de l’heure d’accès ou d’autres facteurs.

Types de limites de débit de l’API

Outre la nature de la mise en œuvre des limites de débit, vous pouvez également classer les limites de débit en fonction de leur effet sur l’utilisateur final. Voici quelques types courants :

  • Limites strictes : Il s’agit de limites strictes qui, lorsqu’elles sont franchies, empêchent totalement l’utilisateur d’accéder à la ressource jusqu’à ce que la limite soit levée.
  • Limites souples : Il s’agit de limites souples qui, lorsqu’elles sont franchies, peuvent encore permettre à l’utilisateur d’accéder à la ressource quelques fois de plus (ou de limiter les requêtes) avant d’en fermer l’accès.
  • Limites dynamiques : Ces limites dépendent de multiples facteurs tels que la charge du serveur, le trafic du réseau, la localisation de l’utilisateur, l’activité de l’utilisateur, la distribution du trafic, etc. et sont modifiées en temps réel pour un fonctionnement efficace des ressources.
  • Restrictions : Ces limites ne coupent pas l’accès à la ressource, mais ralentissent ou mettent en file d’attente les requêtes entrantes jusqu’à ce que la limite soit levée.
  • Limites facturables : Ces limites ne restreignent pas l’accès à la ressource, mais ralentissent ou mettent en file d’attente les requêtes ultérieures jusqu’à ce que la limite soit levée.

Pourquoi est-il nécessaire de limiter le débit ?

Il existe de nombreuses raisons pour lesquelles vous devez mettre en place une limitation de débit dans vos API web. Voici quelques-unes des principales raisons :

1. Protection de l’accès aux ressources

La première raison pour laquelle vous devriez envisager de mettre en place une limite de débit dans votre application est de protéger vos ressources contre la surexploitation par des utilisateurs mal intentionnés. Les attaquants peuvent utiliser des techniques telles que les attaques DDoS pour monopoliser l’accès à vos ressources et empêcher votre application de fonctionner normalement pour les autres utilisateurs. La mise en place d’une limite de débit permet de s’assurer que vous ne facilitez pas la tâche des attaquants qui veulent perturber vos API.

2. Répartition du quota entre les utilisateurs

Outre la protection de vos ressources, la limite de débit vous permet de répartir les ressources de votre API entre les utilisateurs. Cela signifie que vous pouvez créer des modèles de tarification échelonnés et répondre aux besoins dynamiques de vos clients sans que cela n’affecte les autres clients.

3. Amélioration de la rentabilité

La limitation des débits équivaut également à la limitation des coûts. Cela signifie que vous pouvez répartir judicieusement vos ressources entre vos utilisateurs. Avec une structure partitionnée, il est plus facile d’estimer les coûts nécessaires à l’entretien du système. Les éventuels pics peuvent être gérés intelligemment en provisionnant ou en déclassant la quantité adéquate de ressources.

4. Gestion des flux entre les workers

De nombreuses API reposent sur une architecture distribuée qui utilise plusieurs workers/threads/instances pour traiter les requêtes entrantes. Dans une telle structure, vous pouvez utiliser des limites de débit pour contrôler la charge de travail transmise à chaque nœud de travail. Vous pouvez ainsi vous assurer que les nœuds de travail reçoivent des charges de travail équitables et durables. Vous pouvez facilement ajouter ou supprimer des workers en fonction des besoins sans avoir à restructurer l’ensemble de la passerelle API.

Comprendre les limites de rafale

Un autre moyen courant de contrôler l’utilisation de l’API consiste à définir une limite de rafale (également appelée « throttling ») au lieu d’une limite de débit. Les limites de rafale sont des limites de débit mises en œuvre pour un très petit intervalle de temps, par exemple quelques secondes. Par exemple, au lieu de fixer une limite de 1,3 million de requêtes par mois, vous pouvez fixer une limite de 5 requêtes par seconde. Bien que cela équivaille au même trafic mensuel, cela garantit que vos clients ne surchargent pas vos serveurs en envoyant des rafales de milliers de requêtes à la fois.

Dans le cas des limites de rafales, les requêtes sont souvent retardées jusqu’au prochain intervalle au lieu d’être refusées. Il est également souvent recommandé d’utiliser à la fois les limites de débit et les limites de rafale pour un contrôle optimal du trafic et de l’utilisation.

3 Méthodes de mise en œuvre de la limitation de débit

En ce qui concerne la mise en œuvre, il existe quelques méthodes que vous pouvez utiliser pour mettre en place une limitation de débit de l’API dans votre application. Ces méthodes sont les suivantes :

1. Files d’attente de requêtes

L’une des méthodes pratiques les plus simples pour limiter l’accès à l’API consiste à utiliser des files d’attente de requêtes. Les files d’attente de requêtes font référence à un mécanisme dans lequel les requêtes entrantes sont stockées sous la forme d’une file d’attente et traitées l’une après l’autre jusqu’à une certaine limite.

Un cas d’utilisation courant des files d’attente est la séparation des requêtes entrantes des utilisateurs gratuits et payants. Voici comment vous pouvez le faire dans une application Express à l’aide du paquetage express-queue:

const express = require('express')
const expressQueue = require('express-queue');

const app = express()

const freeRequestsQueue = expressQueue({
    activeLimit: 1, // Maximum requests to process at once
    queuedLimit: -1 // Maximum requests allowed in queue (-1 means unlimited)
});

const paidRequestsQueue = expressQueue({
    activeLimit: 5, // Maximum requests to process at once
    queuedLimit: -1 // Maximum requests allowed in queue (-1 means unlimited)
});

// Middleware that selects the appropriate queue handler based on the presence of an API token in the request
function queueHandlerMiddleware(req, res, next) {
    // Check if the request contains an API token
    const apiToken = req.headers['api-token'];

    if (apiToken && isValidToken(apiToken)) {
        console.log("Paid request received")
        paidRequestsQueue(req, res, next);
    } else {
        console.log("Free request received")
        freeRequestsQueue(req, res, next);
     }
}

// Add the custom middleware function to the route
app.get('/route', queueHandlerMiddleware, (req, res) => {
    res.status(200).json({ message: "Processed!" })
});

// Check here is the API token is valid or not
const isValidToken = () => {
    return true;
}

app.listen(3000);

2. Throttling

Le throttling est une autre technique utilisée pour contrôler l’accès aux API. Au lieu de couper l’accès lorsqu’un seuil est atteint, il se concentre sur l’atténuation des pics de trafic de l’API en mettant en œuvre de petits seuils pour de petites plages de temps. Au lieu d’établir une limite de taux comme 3 millions d’appels par mois, le throttling établit des limites de 10 appels par seconde. Dès qu’un client envoie plus de 10 appels en une seconde, les requêtes suivantes dans la même seconde sont automatiquement limitées, mais le client retrouve instantanément l’accès à l’API dans la seconde suivante.

Vous pouvez le mettre en œuvre dans Express à l’aide du paquetage express-throttle. Voici un exemple d’application Express qui montre comment configurer le throttling dans votre application :

const express = require('express')
const throttle = require('express-throttle')

const app = express()

const throttleOptions = {
    "rate": "10/s",
    "burst": 5,
    "on_allowed": function (req, res, next, bucket) {
        res.set("X-Rate-Limit-Limit", 10);
        res.set("X-Rate-Limit-Remaining", bucket.tokens);
        next()
    },
    "on_throttled": function (req, res, next, bucket) {
        // Notify client
        res.set("X-Rate-Limit-Limit", 10);
        res.set("X-Rate-Limit-Remaining", 0);
        res.status(503).send("System overloaded, try again after a few seconds.");
    }
}

// Add the custom middleware function to the route
app.get('/route', throttle(throttleOptions), (req, res) => {
    res.status(200).json({ message: "Processed!" })
});

app.listen(3000);

Vous pouvez tester l’application à l’aide d’un outil de test de charge comme AutoCannon. Vous pouvez installer AutoCannon en exécutant la commande suivante dans votre terminal :

npm install autocannon -g

Vous pouvez tester l’application en utilisant ce qui suit :

autocannon http://localhost:3000/route

Le test utilise 10 connexions simultanées qui envoient des requêtes à l’API. Voici le résultat du test :

Running 10s test @ http://localhost:3000/route

10 connections

┌─────────┬──────┬──────┬───────┬──────┬─────────┬─────────┬───────┐
│ Stat    │ 2.5% │ 50%  │ 97.5% │ 99%  │ Avg     │ Stdev   │ Max   │
├─────────┼──────┼──────┼───────┼──────┼─────────┼─────────┼───────┤
│ Latency │ 0 ms │ 0 ms │ 1 ms  │ 1 ms │ 0.04 ms │ 0.24 ms │ 17 ms │
└─────────┴──────┴──────┴───────┴──────┴─────────┴─────────┴───────┘
┌───────────┬─────────┬─────────┬────────┬─────────┬────────┬─────────┬─────────┐
│ Stat      │ 1%      │ 2.5%    │ 50%    │ 97.5%   │ Avg    │ Stdev   │ Min     │
├───────────┼─────────┼─────────┼────────┼─────────┼────────┼─────────┼─────────┤
│ Req/Sec   │ 16591   │ 16591   │ 19695  │ 19903   │ 19144  │ 1044.15 │ 16587   │
├───────────┼─────────┼─────────┼────────┼─────────┼────────┼─────────┼─────────┤
│ Bytes/Sec │ 5.73 MB │ 5.73 MB │ 6.8 MB │ 6.86 MB │ 6.6 MB │ 360 kB  │ 5.72 MB │
└───────────┴─────────┴─────────┴────────┴─────────┴────────┴─────────┴─────────┘

Req/Bytes counts sampled once per second.
# of samples: 11
114 2xx responses, 210455 non 2xx responses
211k requests in 11.01s, 72.6 MB read

Étant donné que seules 10 requêtes par seconde étaient autorisées (avec une rafale supplémentaire de 5 requêtes), seules 114 requêtes ont été traitées par l’API, et les requêtes restantes ont reçu un code d’erreur 503 demandant d’attendre un certain temps.

3. Algorithmes de limitation de débit

Bien que la limitation de débit semble être un concept simple qui peut être mis en œuvre à l’aide d’une file d’attente, elle peut, en fait, être mise en œuvre de différentes manières offrant divers avantages. Voici quelques algorithmes populaires utilisés pour mettre en œuvre la limitation de débit :

Algorithme à fenêtre fixe

L’algorithme à fenêtre fixe est l’un des algorithmes de limitation de débit les plus simples. Il limite le nombre de requêtes pouvant être traitées dans un intervalle de temps fixe.

Vous définissez un nombre fixe de requêtes, disons 100, qui peuvent être traitées par le serveur API en une heure. Lorsque la 101ème requête arrive, l’algorithme refuse de la traiter. Lorsque l’intervalle de temps est réinitialisé (c’est-à-dire dans l’heure suivante), 100 autres requêtes entrantes peuvent être traitées.

Cet algorithme est simple à mettre en œuvre et fonctionne bien dans de nombreux cas où la limitation du débit côté serveur est nécessaire pour contrôler la bande passante (contrairement à la répartition de la bande passante entre les utilisateurs). Cependant, il peut entraîner un trafic/traitement irrégulier vers les limites de l’intervalle de temps fixé. L’algorithme de la fenêtre coulissante est une meilleure alternative dans les cas où vous avez besoin d’un traitement régulier.

Algorithme à fenêtre glissante

L’algorithme à fenêtre glissante est une variante de l’algorithme de la fenêtre fixe. Au lieu d’utiliser des intervalles de temps fixes prédéfinis, cet algorithme utilise une fenêtre temporelle mobile pour suivre le nombre de requêtes traitées et entrantes.

Au lieu d’examiner les intervalles de temps absolus (de 60 secondes chacun, par exemple), tels que 0s à 60s, 61s à 120s, et ainsi de suite, l’algorithme à fenêtre glissante examine les 60s précédentes à partir du moment où une requête est reçue. Supposons qu’une requête soit reçue à la 82ème seconde ; l’algorithme comptera alors le nombre de requêtes traitées entre 22 et 82 secondes (au lieu de l’intervalle absolu de 60 à 120 secondes) pour déterminer si cette requête peut être traitée ou non. Cela permet d’éviter les situations dans lesquelles un grand nombre de requêtes est traité à la fois à la 59ème et à la 61ème seconde, ce qui surcharge le serveur pendant une très courte période.

Cet algorithme permet de gérer plus facilement le trafic en rafale, mais il peut être plus difficile à mettre en œuvre et à maintenir que l’algorithme à fenêtre fixe.

Algorithme du seau de jetons

Dans cet algorithme, un seau fictif est rempli de jetons, et chaque fois que le serveur traite une requête, un jeton est retiré du seau. Lorsque le seau est vide, le serveur ne peut plus traiter de requêtes. Les autres requêtes sont retardées ou refusées jusqu’à ce que le seau soit à nouveau rempli.

Le seau de jetons est rempli à un rythme fixe (appelé taux de génération de jetons) et le nombre maximal de jetons pouvant être stockés dans le seau est également fixe (appelé profondeur du seau).

En contrôlant le taux de régénération des jetons et la profondeur du seau, vous pouvez contrôler le débit maximal de trafic autorisé par l’API. Le paquet express-throttle que vous avez vu précédemment utilise l’algorithme du seau de jetons pour limiter ou contrôler le flux de trafic de l’API.

Le principal avantage de cet algorithme est qu’il prend en charge le trafic en rafale tant qu’il peut être pris en compte dans la profondeur du seau. Ceci est particulièrement utile pour le trafic imprévisible.

Algorithme du seau percé

L’algorithme du seau percé est un autre algorithme permettant de gérer le trafic des API. Au lieu de maintenir une profondeur de seau qui détermine le nombre de requêtes pouvant être traitées dans un laps de temps donné (comme dans un seau de jetons), il autorise un flux fixe de requêtes à partir du seau, ce qui est analogue à l’écoulement régulier de l’eau à partir d’un seau qui fuit.

Dans ce cas, la profondeur du seau est utilisée pour déterminer le nombre de requêtes qui peuvent être mises en file d’attente avant que le seau ne commence à déborder, c’est-à-dire à refuser les requêtes entrantes.

Le seau percé promet un flux régulier de requêtes et, contrairement au seau de jetons, ne gère pas les pics de trafic.

Meilleures pratiques pour la limitation du débit de l’API

Maintenant que vous savez ce qu’est la limitation de débit de l’API et comment elle est mise en œuvre, voici quelques bonnes pratiques à adopter. Voici quelques bonnes pratiques à prendre en compte lors de sa mise en œuvre dans votre application.

Proposez un niveau gratuit aux utilisateurs pour qu’ils explorent vos services

Lorsque vous envisagez de mettre en place une limite de débit de l’API, essayez toujours de proposer un niveau gratuit adéquat que vos utilisateurs potentiels peuvent utiliser pour essayer votre API. Il n’est pas nécessaire d’être très généreux, mais cela doit être suffisant pour leur permettre de tester confortablement votre API dans leur application de développement.

Bien que les limites de débit de l’API soient essentielles au maintien de la qualité de vos points de terminaison d’API pour vos utilisateurs, un petit niveau gratuit non limité peut vous aider à gagner de nouveaux utilisateurs.

Déterminez ce qui se passe en cas de dépassement de la limite de débit

Lorsqu’un utilisateur dépasse la limite de débit de votre API, vous devez prendre certaines mesures pour garantir une expérience positive à l’utilisateur tout en protégeant vos ressources. Voici quelques-unes des questions que vous devez poser et des considérations que vous devez prendre en compte :

Quel code d’erreur et quel message vos utilisateurs verront-ils ?

La première chose à faire est d’informer vos utilisateurs qu’ils ont dépassé la limite fixée pour le débit de l’API. Pour ce faire, vous devez remplacer la réponse de l’API par un message prédéfini qui explique le problème. Il est important que le code d’état de cette réponse soit 429 « oo Many Requests Il est également d’usage d’expliquer le problème dans le corps de la réponse. Voici un exemple de corps de réponse :

{
    "error": "Too Many Requests",
    "message": "You have exceeded the set API rate limit of X requests per minute. Please try again in a few minutes.",
    "retry_after": 60
}

L’exemple de corps de réponse ci-dessus mentionne le nom et la description de l’erreur et spécifie également une durée (généralement en secondes) après laquelle l’utilisateur peut réessayer d’envoyer des requêtes. Un corps de réponse descriptif comme celui-ci aide les utilisateurs à comprendre ce qui s’est passé et pourquoi ils n’ont pas reçu la réponse qu’ils attendaient. Il leur permet également de savoir combien de temps ils doivent attendre avant d’envoyer une autre requête.

Les nouvelles requêtes seront-elles limitées ou complètement arrêtées ?

Un autre point de décision est de savoir ce qu’il faut faire lorsque la limite de débit de l’API est dépassée par un utilisateur. En général, vous empêchez l’utilisateur d’interagir avec le serveur en renvoyant une réponse 429 Too Many Requests, comme vous l’avez vu ci-dessus. Cependant, vous devriez également envisager une autre approche : le throttling.

Au lieu de couper complètement l’accès aux ressources du serveur, vous pouvez ralentir le nombre total de requêtes que l’utilisateur peut envoyer dans un certain laps de temps. Cette méthode est utile lorsque vous souhaitez donner une petite tape sur les doigts à vos utilisateurs tout en leur permettant de continuer à travailler s’ils réduisent leur volume de requêtes.

Envisagez la mise en cache et la coupure de circuit

Les limites de débit des API sont désagréables : elles empêchent vos utilisateurs d’interagir avec vos services API et de les utiliser. C’est particulièrement grave pour les utilisateurs qui doivent effectuer des requêtes similaires à plusieurs reprises, comme l’accès à un ensemble de données de prévisions météorologiques qui n’est mis à jour qu’une fois par semaine ou la récupération d’une liste d’options pour un menu déroulant qui pourrait être modifié une fois par semaine. Dans ces cas, une approche intelligente consisterait à mettre en place un système de cache.

La mise en cache est une abstraction de stockage à grande vitesse mise en œuvre dans les cas où le volume d’accès aux données est élevé, mais où les données ne changent pas très souvent. Au lieu d’effectuer un appel d’API susceptible d’invoquer plusieurs services internes et d’entraîner de lourdes dépenses, vous pourriez mettre en cache les points de terminaison les plus fréquemment utilisés, de sorte que la deuxième requête soit servie à partir du cache statique, ce qui est généralement plus rapide, moins coûteux et peut réduire la charge de travail de vos services principaux.

Il peut également arriver que vous receviez un nombre anormalement élevé de requêtes de la part d’un utilisateur. Même après avoir fixé une limite de débit, ils atteignent constamment leur capacité et sont limités dans leur débit. Ce type de situation indique qu’il existe un risque d’abus de l’API.

Pour protéger vos services de la surcharge et maintenir une expérience uniforme pour le reste de vos utilisateurs, vous devez envisager de restreindre complètement l’accès de l’utilisateur suspect à l’API. C’est ce qu’on appelle la coupure de circuit, et bien qu’elle semble similaire à la limitation de débit, elle est généralement utilisée lorsque le système est confronté à une surcharge de requêtes et a besoin de temps pour ralentir afin de retrouver sa qualité de service.

Surveillez de près votre configuration

Bien que les limites de débit des API soient destinées à répartir équitablement vos ressources entre vos utilisateurs, elles peuvent parfois causer des problèmes inutiles à vos utilisateurs ou même indiquer une activité suspecte.

La mise en place d’une solution de surveillance robuste pour votre API peut vous aider à comprendre à quelle fréquence les limites de taux sont atteintes par vos utilisateurs, si vous devez ou non reconsidérer les limites générales tout en gardant à l’esprit la charge de travail moyenne de vos utilisateurs et identifier les utilisateurs qui atteignent fréquemment leurs limites (ce qui pourrait indiquer qu’ils ont besoin d’une augmentation prochaine de leurs limites ou qu’ils doivent être surveillés pour toute activité suspecte). Dans tous les cas, une configuration de surveillance active vous aidera à mieux comprendre l’impact des limites de débit de votre API.

Mettez en œuvre la limitation de débit à plusieurs niveaux

La limitation de débit peut être mise en œuvre à plusieurs niveaux (utilisateur, application ou système). De nombreuses personnes commettent l’erreur de définir des limites de débit à un seul de ces niveaux et de s’attendre à ce qu’elles couvrent tous les cas possibles. Bien qu’il ne s’agisse pas exactement d’un anti-modèle, cela peut s’avérer inefficace dans certains cas.

Si les requêtes entrantes surchargent l’interface réseau de votre système, votre limitation de débit au niveau de l’application risque de ne même pas pouvoir optimiser les charges de travail. Il est donc préférable de définir les règles de limitation de débit à plusieurs niveaux, de préférence dans les couches supérieures de votre architecture, afin d’éviter la création de goulets d’étranglement.

Utilisation des limites de débit de l’API

Dans cette section, vous apprendrez à tester les limites de débit de l’API pour un point de terminaison API donné et à mettre en œuvre un contrôle de l’utilisation sur votre client afin de vous assurer que vous ne finirez pas par épuiser les limites de votre API distante.

Comment tester les limites de débit de l’API

Pour identifier la limite de débit d’une API, votre première approche doit toujours être de lire la documentation de l’API afin de déterminer si les limites ont été clairement définies. Dans la plupart des cas, la documentation de l’API vous indiquera la limite et la manière dont elle a été mise en œuvre. Vous ne devez recourir au « test » de la limite de taux de l’API pour l’identifier que si vous ne pouvez pas l’identifier à partir de la documentation de l’API, de l’assistance ou de la communauté. En effet, tester une API pour trouver sa limite de débit signifie que vous finirez par épuiser votre limite de débit au moins une fois, ce qui peut entraîner des coûts financiers et/ou l’indisponibilité de l’API pendant une certaine durée.

Si vous cherchez à identifier manuellement la limite de débit, commencez par utiliser un outil de test d’API simple comme Postman pour effectuer des requêtes manuellement à l’API et voir si vous pouvez épuiser sa limite de débit. Si ce n’est pas le cas, vous pouvez alors utiliser un outil de test de charge comme Autocannon ou Gatling pour simuler un grand nombre de requêtes et voir combien de requêtes sont traitées par l’API avant qu’elle ne commence à répondre avec un code d’état 429.

Une autre approche peut consister à utiliser un outil de vérification des limites de débit tel que celui d’AppBrokers rate-limit-test-tool. Des outils dédiés comme celui-ci automatisent le processus pour vous et vous fournissent également une interface utilisateur pour analyser soigneusement les résultats du test.

Toutefois, si vous n’êtes pas sûr de la limite de débit d’une API, vous pouvez toujours essayer d’estimer vos besoins en termes de requêtes et de définir des limites côté client afin de vous assurer que le nombre de requêtes de votre application ne dépasse pas ce chiffre. Vous apprendrez comment procéder dans la section suivante.

Comment limiter les appels à l’API

Si vous faites des appels à une API à partir de votre code, vous voudrez peut-être mettre en place un système de throttling de votre côté pour vous assurer que vous ne faites pas accidentellement trop d’appels à l’API et que vous n’épuisez pas votre limite d’API. Il existe plusieurs façons de procéder. L’une des plus courantes consiste à utiliser la méthode throttle de la bibliothèque utilitaire lodash.

Avant de commencer à limiter les appels à l’API, vous devez créer une API. Voici un exemple de code pour une API basée sur Node.js qui imprime dans la console le nombre moyen de requêtes qu’elle reçoit par minute :

const express = require('express');
const app = express();

// maintain a count of total requests
let requestTotalCount = 0;
let startTime = Date.now();

// increase the count whenever any request is received
app.use((req, res, next) => {
    requestTotalCount++;
    next();
});

// After each second, print the average number of requests received per second since the server was started
setInterval(() => {
    const elapsedTime = (Date.now() - startTime) / 1000;
    const averageRequestsPerSecond = requestTotalCount / elapsedTime;
    console.log(`Average requests per second: ${averageRequestsPerSecond.toFixed(2)}`);
}, 1000);

app.get('/', (req, res) => {
    res.send('Hello World!');
});

app.listen(3000, () => {
    console.log('Server listening on port 3000!');
});

Une fois cette application exécutée, elle affichera le nombre moyen de requêtes reçues chaque seconde :

Average requests per second: 0
Average requests per second: 0
Average requests per second: 0

Ensuite, créez un nouveau fichier JavaScript appelé test-throttle.js et enregistrez-y le code suivant :

// function that calls the API and prints the response
const request = () => {
    fetch('http://localhost:3000')
    .then(r => r.text())
    .then(r => console.log(r))
}

// Loop to call the request function once every 100 ms, i.e., 10 times per second
setInterval(request, 100)

Une fois que vous aurez exécuté ce script, vous remarquerez que le nombre moyen de requêtes pour le serveur s’élève à près de 10 :

Average requests per second: 9.87
Average requests per second: 9.87
Average requests per second: 9.88

Que se passerait-il si cette API n’autorisait que 6 requêtes par seconde, par exemple ? Vous souhaiteriez maintenir votre nombre moyen de requêtes en dessous de ce chiffre. Toutefois, si votre client envoie une requête en fonction d’une activité de l’utilisateur, comme le clic d’un bouton ou un défilement, il se peut que vous ne puissiez pas limiter le nombre de fois où l’appel à l’API est déclenché.

La fonction throttle() de la bibliothèque lodash peut vous aider. Tout d’abord, installez la bibliothèque en exécutant la commande suivante :

npm install lodash

Ensuite, mettez à jour le fichier test-throttle.js pour qu’il contienne le code suivant :

// import the lodash library
const { throttle } = require('lodash');

// function that calls the API and prints the response
const request = () => {
    fetch('http://localhost:3000')
    .then(r => r.text())
    .then(r => console.log(r))
}

// create a throttled function that can only be called once every 200 ms, i.e., only 5 times every second
const throttledRequest = throttle(request, 200)

// loop this throttled function to be called once every 100 ms, i.e., 10 times every second
setInterval(throttledRequest, 100)

Maintenant, si vous regardez les journaux du serveur, vous verrez une sortie similaire :

Average requests per second: 4.74
Average requests per second: 4.80
Average requests per second: 4.83

Cela signifie que même si votre application appelle la fonction request 10 fois par seconde, la fonction de throttling veille à ce qu’elle ne soit appelée que 5 fois par seconde, ce qui vous permet de rester en dessous de la limite de débit. Voilà comment vous pouvez mettre en place un throttling côté client pour éviter d’épuiser les limites de débit de l’API.

Erreurs courantes liées aux limites de débit des API

Lorsque vous travaillez avec des API à débit limité, vous pouvez rencontrer diverses réponses indiquant qu’une limite de débit a été dépassée. Dans la plupart des cas, vous recevrez le code d’état 429 accompagné d’un message similaire à l’un des suivants :

  • Calls to this API have exceeded the rate limit
  • API rate limit exceeded
  • 429 too many requests

Toutefois, le message que vous recevez dépend de l’implémentation de l’API que vous utilisez. Cette implémentation peut varier, et certaines API peuvent même ne pas utiliser le code d’état 429. Voici d’autres types de codes d’erreur et de messages relatifs à la limite de débit que vous pouvez recevoir lorsque vous travaillez avec des API à débit limité :

  • 403 Forbidden ou 401 Unauthorized : Certaines API peuvent commencer à considérer vos requêtes comme non autorisées et vous refuser ainsi l’accès à la ressource
  • 503 Service Unavailable ou 500 Internal Server Error : Si une API est surchargée par des requêtes entrantes, elle peut commencer à envoyer des messages d’erreur 5XX indiquant que le serveur n’est pas en bonne santé. Il s’agit généralement d’un problème temporaire qui est résolu par le fournisseur de services en temps voulu.

Comment les principaux fournisseurs d’API mettent-ils en œuvre les limites de débit de l’API ?

Lorsque vous définissez la limite de débit de votre API, il peut être utile d’examiner la manière dont certains des principaux fournisseurs d’API procèdent :

  • Discord : Discord met en œuvre la limitation de débit de deux manières : il existe une limite de débit globale de 50 requêtes par seconde. Outre la limite globale, il existe également des limites de taux spécifiques aux routes que vous devez garder à l’esprit. Vous pouvez lire tout cela dans cette documentation. Lorsque la limite de taux est dépassée, vous recevez une réponse HTTP 429 avec une valeur retry_after que vous pouvez utiliser pour attendre avant d’envoyer une autre requête.
  • Twitter : Twitter a également des limites de taux spécifiques aux routes que vous pouvez trouver dans leur documentation. Une fois la limite de débit dépassée, vous recevrez une réponse HTTP 429 avec une valeur d’en-tête x-rate-limit-reset qui vous indiquera quand vous pourrez reprendre l’accès.
  • Reddit : Le wiki API archivé de Reddit indique que la limite d’accès à l’API Reddit est de 60 requêtes par minute (via OAuth2 uniquement). La réponse à chaque appel à l’API Reddit renvoie les valeurs des en-têtes X-Ratelimit-Used, X-Ratelimit-Remaining, et X-Ratelimit-Reset, ce qui vous permet de déterminer quand la limite pourrait être dépassée et de quelle manière
  • Facebook : Facebook fixe également des limites de débit basées sur les routes. Par exemple, les appels effectués à partir d’applications basées sur Facebook sont limités à 200 * (nombre d’utilisateurs de l’application) requêtes par heure. Vous trouverez tous les détails ici. Les réponses de l’API Facebook contiendront un en-tête X-App-Usage ou X-Ad-Account-Usage pour vous aider à comprendre quand votre utilisation sera limitée.

Résumé

Lorsque vous créez des API, il est essentiel d’assurer un contrôle optimal du trafic. Si vous ne surveillez pas de près la gestion de votre trafic, vous vous retrouverez rapidement avec une API surchargée et non fonctionnelle. Inversement, lorsque vous travaillez avec une API à débit limité, il est important de comprendre comment fonctionne la limitation du débit et comment vous devez utiliser l’API pour garantir une disponibilité et une utilisation maximales.

Dans ce guide, vous avez appris ce qu’est la limitation de débit de l’API, pourquoi elle est nécessaire, comment elle peut être mise en œuvre et quelques bonnes pratiques que vous devez garder à l’esprit lorsque vous travaillez avec des limites de débit de l’API.

Découvrez l’hébergement d’applications de Kinsta et lancez votre prochain projet Node.js dès aujourd’hui !

Vous travaillez avec une API à débit limité ? Ou vous avez mis en place une limitation de débit dans votre propre API ? Faites-nous en part dans les commentaires ci-dessous !