How to Throttle API with Django Rest Framework



In the realm of building APIs using the renowned Django Rest Framework (DRF), one must skillfully navigate the challenges posed by managing the rate at which clients can unleash their torrent of requests upon your API endpoints. Throttling mechanisms come to the rescue by effectively safeguarding against potential abuse, protecting precious resources, and fostering an environment of equitable usage among clients. In this in−depth discourse, we shall embark upon an enlightening journey, exploring the multifaceted realm of implementing throttling techniques within your DRF−powered API. Brace yourself for a captivating exploration of the built−in throttling classes at your disposal, as well as the intricate art of crafting custom throttling rules tailored to your unique needs.

The Marvelous Pantheon of Built−in Throttling Classes

Within the majestic realm of Django Rest Framework, a veritable cornucopia of built−in throttling classes awaits your perusal. Let us unveil a select few of these awe−inspiring classes, each with its own distinct purpose:

  • AnonRateThrottle: This class limits the number of requests that anonymous (unauthenticated) clients can make within a specific time frame.

  • UserRateThrottle: This class restricts the number of requests that authenticated clients can make within a given time interval.

  • ScopedRateThrottle: With this class, you can define custom throttling rates for different parts of your API using scopes.

To unlock the true potential of these magnificent throttling classes, you need merely integrate them into the illustrious tapestry of your Django project's settings.py file, nestled within the warm embrace of the REST_FRAMEWORK settings.

Configuring Throttling: To configure throttling for your DRF−based API, follow these steps:

  • Open your project's settings.py file.

  • Locate the REST_FRAMEWORK dictionary and add the desired throttling classes to the DEFAULT_THROTTLE_CLASSES list.

  • Define the throttling rates in the DEFAULT_THROTTLE_RATES dictionary, associating a rate with each class.

REST_FRAMEWORK = {
    'DEFAULT_THROTTLE_CLASSES': [
        'rest_framework.throttling.AnonRateThrottle',
        'rest_framework.throttling.UserRateThrottle',
        'rest_framework.throttling.ScopedRateThrottle',
    ],
    'DEFAULT_THROTTLE_RATES': {
        'anon': '100/hour',
        'user': '1000/day',
        'custom': '50/hour',
    }
}

In this example, we have defined the following throttling rates:

  • Anonymous clients can make up to 100 requests per hour.

  • Authenticated clients can make up to 1000 requests per day.

  • A custom scope allows for 50 requests per hour.

Applying Throttling to Views: Throttling rules can be applied to views in two ways: class−based views and function−based views.

1. Class−based Views

  • Use the throttle_classes attribute in your view class and specify the desired throttling classes.

  • Additionally, you can set the throttle_scope attribute to specify a custom scope for ScopedRateThrottle.

Example using class−based views

from rest_framework.throttling import UserRateThrottle, ScopedRateThrottle
from rest_framework.views import APIView

class MyApiView(APIView):
    throttle_classes = [UserRateThrottle, ScopedRateThrottle]
    throttle_scope = 'custom'

    def get(self, request):
        # Your view logic here
        pass

2. Function−based Views

  • Use the @throttle_classes decorator on your view function and provide the desired throttling classes.

Example using function−based views

from rest_framework.throttling import UserRateThrottle, ScopedRateThrottle
from rest_framework.decorators import api_view, throttle_classes

@api_view(['GET'])
@throttle_classes([UserRateThrottle, ScopedRateThrottle])
def my_api_view(request):
    # Your view logic here
    pass

Creating Custom Throttling: If the built−in throttling classes don't meet your requirements, you can create custom throttling classes by extending the SimpleRateThrottle class and implementing the get_cache_key() method. The scope attribute defines the scope of the custom throttling class.

Example of a custom throttling class

from rest_framework.throttling import SimpleRateThrottle

class CustomThrottle(SimpleRateThrottle):
    scope = 'custom'

    def get_cache_key(self, request, view):
        # Custom logic to generate the cache key
        pass

Throttling does not produce any output that is visible to the user. Instead, it enforces rate limits on API requests.

For example, if a client exceeds the rate limit set by the UserRateThrottle, the server will return an HTTP response similar to the following:

HTTP/1.1 429 Too Many Requests
Content−Type: application/json
Retry−After: 60
{
    "detail": "Request was throttled. Expected availability in 60 seconds."
}

Conclusion

And so, dear reader, we conclude our mesmerizing expedition through the realms of API throttling with Django Rest Framework. We have unraveled the secrets of the built−in throttling classes, empowered ourselves with the knowledge of configuration, and explored the art of applying throttling to our majestic views. Moreover, we have glimpsed the boundless potential of crafting our own custom throttling classes, giving life to our creative visions.


Advertisements