DRF Throttling: Scope gebruiken – Vergelijking tussen ScopedRateThrottle en UserRateThrottle‑subclass
In DRF komen twee veelvoorkomende patronen voor bij scope‑gebaseerde throttling.
- Patroon A: Maak een eigen klasse door
UserRateThrottle(ofSimpleRateThrottle) te erven, stel eenscopein en koppel deze direct aan de view viathrottle_classes. - Patroon B: Registreer
ScopedRateThrottleinDEFAULT_THROTTLE_CLASSESen geef in de view alleenthrottle_scope = "login".
Vraag: "Is het uiteindelijk hetzelfde?"
Voor een enkel rate‑limiet gebaseerd op ‘userID (of niet‑geauthenticeerde IP) + scope’ zijn de resultaten vrijwel identiek. Verschillen ontstaan in de manier van toepassen (foutpreventie), uitbreidbaarheid (meerdere policies/aanpassingen) en de code‑structuur (configuratie‑gericht vs code‑gericht).
1. Gemeenschappelijke basis: Beide gebruiken “scope + (userID of IP)” als sleutel
ScopedRateThrottlebouwt de sleutel uitscope + userID/IPwanneerthrottle_scopeaanwezig is, en zoekt de bijbehorende rate inDEFAULT_THROTTLE_RATES.UserRateThrottlebeperkt standaard opuserIDvoor geauthenticeerde gebruikers en op IP voor niet‑geauthenticeerde. Voor meerdere scopes wordt aanbevolen een subclass te maken.
2. Verschil 1: Waar wordt de scope gedefinieerd? – View‑attribuut vs Class‑attribuut
Patroon A: Scope vast in de klasse (expliciet)
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]
- De scope is vast in de klasse.
- De view hoeft alleen aan te geven dat deze klasse gebruikt wordt.
- Minder kans op typfouten in de scope‑string; de klasse fungeert als documentatie.
Patroon B: Scope in de view, gedeelde throttle (configuratie‑gericht)
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"
- De scope staat direct in de view.
- De gedeelde throttle (
ScopedRateThrottle) bepaalt of het een login‑scope is en haalt de rate uit de settings. - Code is korter en policies zijn centraal beheerd.
3. Verschil 2: Wie garandeert de toepassing? – Standaardregistratie vs View‑specifieke installatie
Patroon B: Veel misvattingen
Het toevoegen van ScopedRateThrottle aan DEFAULT_THROTTLE_CLASSES heeft geen effect op views zonder throttle_scope. Dus je hoeft je geen zorgen te maken dat alle API‑punten ineens geblokkeerd worden.
Patroon A: Sterke punten
Je kunt zonder globale instellingen een specifieke view een throttle toewijzen. Dit is handig als je de settings niet kunt aanpassen of alleen een bepaald app/endpoint wilt afdwingen.
4. Verschil 3: Schaalbaarheid – Wanneer A voordeliger wordt
De twee patronen lijken gelijk voor één scope en één rate per view. Vanaf daar divergeren ze.
1) Meerdere throttles (burst + sustained) op één view
DRF laat zien hoe je meerdere UserRateThrottle‑subclasses kunt gebruiken:
class Burst(UserRateThrottle):
scope = "burst"
class Sustained(UserRateThrottle):
scope = "sustained"
class SearchView(APIView):
throttle_classes = [Burst, Sustained]
Met alleen ScopedRateThrottle is het lastig om twee scopes op één view te hanteren; je hebt een subclass nodig (of een aangepaste implementatie).
2) Veranderen van de basis voor throttling
ScopedRateThrottle werkt standaard op userID/IP. In de praktijk ontstaan vaak andere vereisten:
- Login: limiet op IP + gebruikersnaam (tegen account‑targeting).
- Organisatie/tenant: limiet op
tenant_id. - API‑sleutel: limiet op de sleutel zelf.
Dit vereist een aangepaste get_cache_key()‑implementatie, wat leidt tot een subclass (Patroon A). DRF moedigt ook custom throttles aan.

5. Welke aanpak kiezen?
Voor de meeste “view‑specifieke rate limits” → Patroon B (ScopedRateThrottle)
- Minder code
- Policies centraal in settings
- Alleen
throttle_scopein de view - Views zonder scope worden niet beperkt
Als een van de volgende geldt → Patroon A (subclass/aanpassing)
- Meerdere limieten (burst + sustained) op één view
- Een custom basis (bijv. username+IP, tenant, API‑sleutel)
- Je kunt de globale settings niet aanpassen en wil een specifieke view afdwingen
- Je wilt de policy documenteren via de klassenaam
Meer lezen: