# Comparación de dos enfoques de throttling con scope en DRF: ScopedRateThrottle vs herencia de UserRateThrottle En DRF, al aplicar throttling basado en scope, suelen aparecer dos patrones comunes. * **Enfoque A**: Heredar de `UserRateThrottle` (o `SimpleRateThrottle`) y crear una clase personalizada con **scope** fijado, luego asignarla directamente a `throttle_classes` de la vista. * **Enfoque B**: Registrar `ScopedRateThrottle` en `DEFAULT_THROTTLE_CLASSES` y en la vista solo indicar `throttle_scope = "login"`. Para responder a la pregunta “¿son esencialmente iguales?”: >Si el objetivo es limitar la tasa por user ID (o IP sin autenticar) + scope, los resultados son **casi idénticos**. La diferencia radica en la forma de aplicación (prevención de errores, extensibilidad, estructura de código) y, por tanto, en la elección del patrón. --- ## Puntos en común: ambos crean la clave con “scope + (user id o IP)” {#sec-431a00e0f2d6} * `ScopedRateThrottle` construye la clave con *scope + userID/IP* cuando la vista tiene `throttle_scope`, y busca la tasa correspondiente en `DEFAULT_THROTTLE_RATES`. * `UserRateThrottle` también limita por *user id* para usuarios autenticados y por *IP* para no autenticados; para usar varias tasas, DRF sugiere heredar la clase y cambiar el scope. --- ## Diferencia 1) ¿Dónde colocar el scope?: atributo de la vista vs atributo de la clase {#sec-d624b1b24a23} ### Enfoque A: scope fijo en la clase (explícito) {#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] ``` * El scope está **fijado en la clase**. * La vista solo declara que usará esa clase. * Se reducen los errores tipográficos en el scope, ya que el nombre de la clase actúa como documentación. ### Enfoque B: scope en la vista, throttling común (centrado en la configuración) {#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" ``` * El scope se coloca **directamente en la vista**. * El `ScopedRateThrottle` común interpreta que la vista pertenece al scope y aplica la tasa desde la configuración. * El código es más corto y la política se gestiona en un solo lugar. --- ## Diferencia 2) ¿Quién garantiza la aplicación?: registro por defecto vs equipamiento por vista {#sec-693e9b27f525} ### Puntos clave del Enfoque B (mucha confusión) {#sec-579edda7168e} Incluso si `ScopedRateThrottle` está en `DEFAULT_THROTTLE_CLASSES`, **no se aplica a las vistas sin `throttle_scope`**. No hay riesgo de bloquear toda la API al registrar globalmente. ### Ventaja del Enfoque A {#sec-1d7d8c13bc83} Se puede **equipar un throttle específico a una vista** sin tocar la configuración global, útil cuando el entorno no permite cambios masivos o cuando solo ciertos endpoints deben ser restringidos. --- ## Diferencia 3) Escalabilidad: cuando se supera el “un solo límite” el Enfoque A gana ventaja {#sec-76818ce0201b} La similitud se mantiene hasta “una vista, un scope, una tasa”. Más allá, las diferencias se hacen evidentes. ### 1) Aplicar múltiples throttles (burst + sustained) a una vista {#sec-c0ea02305999} DRF muestra un patrón con varias `UserRateThrottle`: ```python class Burst(UserRateThrottle): scope = "burst" class Sustained(UserRateThrottle): scope = "sustained" class SearchView(APIView): throttle_classes = [Burst, Sustained] ``` Con `ScopedRateThrottle` solo, es difícil expresar “dos scopes en una vista”; se necesita una clase adicional o una implementación personalizada. ### 2) Cambiar el criterio de limitación {#sec-39de8e67072d} `ScopedRateThrottle` se basa en *user id / IP*. En la práctica surgen necesidades como: * **IP + nombre de usuario** para proteger contra ataques dirigidos a cuentas. * **tenant_id** para limitar por organización. * **API key** para limitar por clave. Estas situaciones requieren sobrescribir `get_cache_key()` y, por tanto, **heredar y personalizar** el throttle (Enfoque A). DRF también recomienda crear throttles personalizados en estos casos. --- ![Dos llaves para abrir la conexión API](/media/editor_temp/6/e98f026a-a38e-43ca-8c86-fa7966dd3cdf.png) ## ¿Cuál elegir? {#sec-1cf080d47909} ### Para la mayoría de los “rate limits por vista” → Enfoque B (ScopedRateThrottle) {#sec-924ae91c07d2} * Código mínimo. * Política gestionada en `settings`. * Solo se aplica a vistas con `throttle_scope`. ### Si se cumple al menos una de las siguientes condiciones → Enfoque A (herencia/Clase personalizada) {#sec-335f8d95a231} * Se necesitan **múltiples límites** (burst + sustained) en la misma vista. * El criterio de limitación no es *user/IP* sino algo personalizado (usuario+IP, tenant, API key, etc.). * Se desea evitar cambios globales y equipar throttles solo a vistas específicas. * Se quiere que el nombre de la clase sirva como documentación de la política. **Artículo relacionado:** - [Domina el throttling en DRF: configuración, aplicación y guía de personalización](/ko/whitedec/2026/1/26/drf-throttling-complete-guide/)