# Comparaison des deux approches de throttling basé sur le scope dans DRF : ScopedRateThrottle vs héritage de UserRateThrottle Dans DRF, deux schémas courants apparaissent lorsqu’on applique un throttling basé sur le scope. * **Approche A** : hériter de `UserRateThrottle` (ou `SimpleRateThrottle`) pour créer une classe personnalisée contenant le `scope`, puis l’attacher directement à la vue via `throttle_classes`. * **Approche B** : enregistrer `ScopedRateThrottle` dans `DEFAULT_THROTTLE_CLASSES` et ne préciser que `throttle_scope = "login"` dans la vue. Pour répondre à la question « est-ce que les deux donnent le même résultat ? » : > **Si l’on veut simplement limiter la vitesse par *userID (ou IP non authentifié) + scope*, les résultats sont quasiment identiques.** > La différence réside dans la façon d’appliquer (prévention d’erreurs), l’évolutivité (plusieurs politiques / critères personnalisés) et la structure du code (configuration centralisée vs code local). --- ## Points communs : les deux créent une clé « scope + (user id ou IP) » {#sec-431a00e0f2d6} * `ScopedRateThrottle` construit la clé en combinant le `scope` (s’il est présent dans la vue) avec l’ID utilisateur ou l’IP, puis applique le taux correspondant trouvé dans `DEFAULT_THROTTLE_RATES`. * `UserRateThrottle` limite également par ID utilisateur (authentifié) ou IP (non authentifié) et, pour gérer plusieurs scopes, DRF propose d’hériter de la classe et de définir un `scope` différent. --- ## Différence 1) Où placer le scope : propriété de la vue ou de la classe {#sec-d624b1b24a23} ### Approche A : scope fixé dans la classe (explicite) {#sec-8806ad9d3f5f} ```python from rest_framework.throttling import UserRateThrottle from rest_framework.views import APIView class CustomDomainSaveThrottle(UserRateThrottle): scope = "custom_domain_save" class SaveCustomDomainView(APIView): throttle_classes = [CustomDomainSaveThrottle] ``` * Le `scope` est **défini dans la classe**. * La vue indique simplement qu’elle utilise cette classe. * On évite les fautes de frappe dans le `scope` (la classe sert de documentation). ### Approche B : scope dans la vue, throttling commun (centré sur la configuration) {#sec-21174dce63ed} ```python REST_FRAMEWORK = { "DEFAULT_THROTTLE_CLASSES": [ "rest_framework.throttling.ScopedRateThrottle", ], "DEFAULT_THROTTLE_RATES": { "login": "5/min", } } from rest_framework.views import APIView class LoginView(APIView): throttle_scope = "login" ``` * Le `scope` est **déclaré directement dans la vue**. * Le throttling commun (`ScopedRateThrottle`) lit ce `scope` et applique le taux défini dans les settings. * Le code est plus court et la politique est gérée en un seul endroit. --- ## Différence 2) Qui garantit l’application : enregistrement global ou montage par vue {#sec-693e9b27f525} ### Point clé de l’approche B (souvent mal compris) {#sec-579edda7168e} Même si `ScopedRateThrottle` est dans `DEFAULT_THROTTLE_CLASSES`, il **ne s’applique pas aux vues sans `throttle_scope`**. Il n’est donc pas nécessaire de craindre que l’ajout global bloque toutes les API. ### Avantage de l’approche A {#sec-1d7d8c13bc83} On peut **ajouter un throttling spécifique à une vue** sans toucher la configuration globale. C’est utile lorsqu’on ne peut pas modifier les settings ou lorsqu’on veut forcer une politique uniquement sur un endpoint particulier. --- ## Différence 3) Évolutivité : l’approche A devient préférable au-delà d’une seule restriction {#sec-76818ce0201b} Les deux approches semblent identiques tant qu’on a **une seule restriction par vue**. Au-delà, les différences apparaissent. ### 1) Appliquer plusieurs throttles (burst + sustained) à une même vue {#sec-c0ea02305999} DRF montre un exemple d’utilisation de plusieurs `UserRateThrottle` pour gérer un burst et un sustained. ```python class Burst(UserRateThrottle): scope = "burst" class Sustained(UserRateThrottle): scope = "sustained" class SearchView(APIView): throttle_classes = [Burst, Sustained] ``` Avec `ScopedRateThrottle`, il est difficile d’associer deux scopes à une même vue sans créer de classes supplémentaires. ### 2) Changer le critère de limitation (pas seulement user/IP) {#sec-39de8e67072d} `ScopedRateThrottle` se base sur l’ID utilisateur ou l’IP. En pratique, on peut vouloir limiter par : * IP + nom d’utilisateur (pour contrer les attaques ciblées sur un compte) * `tenant_id` (pour les applications multi‑tenant) * Clé API (pour les clés individuelles) Ces scénarios nécessitent de surcharger `get_cache_key()` ou d’utiliser une classe personnalisée, ce qui conduit naturellement à l’approche A. --- ![Deux clés ouvrant la connexion API](/media/editor_temp/6/e98f026a-a38e-43ca-8c86-fa7966dd3cdf.png) ## Quelle approche choisir ? {#sec-1cf080d47909} ### Pour la plupart des cas de *rate limit par vue* → Approche B (ScopedRateThrottle) {#sec-924ae91c07d2} * Code minimal * Politique centralisée dans les settings * Seule la vue avec `throttle_scope` est affectée ### Si l’un des points suivants s’applique → Approche A (héritage / classe personnalisée) {#sec-335f8d95a231} * On veut appliquer plusieurs restrictions (burst + sustained) à une même vue * Le critère de limitation n’est pas *user/IP* mais un critère personnalisé (username+IP, tenant, clé API, etc.) * On ne peut pas modifier les settings globaux et on veut forcer la politique sur une vue spécifique * On souhaite que le nom de la classe serve de documentation explicite **Article lié :** - [Maîtriser le throttling dans DRF : configuration, application, guide de personnalisation](/ko/whitedec/2026/1/26/drf-throttling-complete-guide/)