Setting up and customizing throttling rates

Introduction

Advanced throttling allows you to implement complex rate limiting logic tailored to your application’s specific requirements. This tutorial will cover advanced throttling customization and provide a full example use case.

Advanced Throttling Customization

Custom Throttling Classes

You can create custom throttling classes to implement more specific throttling logic based on user roles, request types, or other criteria. Here’s an example of creating a custom throttling class:

  1. BurstRateThrottle: Allows a high rate of requests for a short period.
  2. SustainedRateThrottle: Allows a moderate rate of requests over a longer period.

Example: Custom Throttling Classes

Step 1: Create Custom Throttling Classes

Create custom throttling classes by subclassing UserRateThrottle and defining the rate attribute:

# myapp/throttling.py

from rest_framework.throttling import UserRateThrottle

class BurstRateThrottle(UserRateThrottle):
    rate = '5/minute'  # Allow 5 requests per minute

class SustainedRateThrottle(UserRateThrottle):
    rate = '100/day'  # Allow 100 requests per day

Step 2: Apply Custom Throttling Classes to Views

Apply the custom throttling classes to your views:

# myapp/views.py

from rest_framework import generics
from .models import Product
from .serializers import ProductSerializer
from .throttling import BurstRateThrottle, SustainedRateThrottle

class ProductListView(generics.ListCreateAPIView):
    queryset = Product.objects.all()
    serializer_class = ProductSerializer
    throttle_classes = [BurstRateThrottle, SustainedRateThrottle]

class ProductDetailView(generics.RetrieveUpdateDestroyAPIView):
    queryset = Product.objects.all()
    serializer_class = ProductSerializer
    throttle_classes = [BurstRateThrottle, SustainedRateThrottle]

Full Example Use Case

Use Case: E-commerce API with Different Rate Limits for Free and Premium Users

In this example, we’ll set up an e-commerce API with different rate limits for free and premium users. Free users have lower rate limits, while premium users have higher rate limits.

Step 1: Define Models

Define a simple User model with a premium field to distinguish between free and premium users:

# myapp/models.py

from django.contrib.auth.models import AbstractUser
from django.db import models

class User(AbstractUser):
    premium = models.BooleanField(default=False)

class Product(models.Model):
    name = models.CharField(max_length=100)
    category = models.CharField(max_length=50)
    description = models.TextField()
    price = models.DecimalField(max_digits=10, decimal_places=2)
    stock = models.IntegerField()

    def __str__(self):
        return self.name
Step 2: Create Custom Throttling Classes

Create custom throttling classes for free and premium users:

# myapp/throttling.py

from rest_framework.throttling import UserRateThrottle

class FreeUserThrottle(UserRateThrottle):
    rate = '10/day'  # Allow 10 requests per day for free users

    def get_cache_key(self, request, view):
        if request.user.is_authenticated and not request.user.premium:
            return self.cache_format % {
                'scope': self.scope,
                'ident': request.user.pk,
            }
        return None

class PremiumUserThrottle(UserRateThrottle):
    rate = '1000/day'  # Allow 1000 requests per day for premium users

    def get_cache_key(self, request, view):
        if request.user.is_authenticated and request.user.premium:
            return self.cache_format % {
                'scope': self.scope,
                'ident': request.user.pk,
            }
        return None
Step 3: Apply Throttling Classes to Views

Apply the custom throttling classes to your views:

# myapp/views.py

from rest_framework import generics
from .models import Product
from .serializers import ProductSerializer
from .throttling import FreeUserThrottle, PremiumUserThrottle

class ProductListView(generics.ListCreateAPIView):
    queryset = Product.objects.all()
    serializer_class = ProductSerializer
    throttle_classes = [FreeUserThrottle, PremiumUserThrottle]

class ProductDetailView(generics.RetrieveUpdateDestroyAPIView):
    queryset = Product.objects.all()
    serializer_class = ProductSerializer
    throttle_classes = [FreeUserThrottle, PremiumUserThrottle]
Step 4: Update Settings

Ensure the default throttle classes are not set globally since we’re using custom classes per view:

# myproject/settings.py

INSTALLED_APPS = [
    ...
    'rest_framework',
    ...
]

REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': [
        'rest_framework.authentication.SessionAuthentication',
        'rest_framework.authentication.BasicAuthentication',
    ],
}

Conclusion

This tutorial covered advanced throttling customization in Django Rest Framework (DRF) with a detailed example use case. By implementing custom throttling classes, you can set different rate limits for different user roles, ensuring fair usage and protecting your API from abuse. This approach allows you to tailor your API’s rate limiting to specific requirements, providing a better user experience and efficient resource management.


Tags: Advanced Throttling in Django Rest Framework, DRF custom throttling tutorial, rate limiting in DRF, Django API throttling customization