Skip to content

API THROTTLING

Omariba Collins edited this page Feb 4, 2023 · 4 revisions

API THROTTLING

What is API throttling ?

Also called Rate limiting.

It is controlling the rate of requests that clients can make to an API. This can be done for various reasons but mainly to prevent abuse of an API.

How it works

The IP address of an incoming request is used to generate a unique key to throttle against. For authenticated users, the user id is used to generate a unique key to throttle against.

How to implement it

In this implementation I assume you know how to setup a django project. I have setup a project with a blog app.

Set the throttling policy

Throttling classes are inbuilt into the Django Rest Framework hence no library needs to be installed.

In the settings.py file add this.

REST_FRAMEWORK = {
    'DEFAULT_THROTTLE_CLASSES': [
        'rest_framework.throttling.UserRateThrottle',
        'rest_framework.throttling.AnonRateThrottle'
    ],
    'DEFAULT_THROTTLE_RATES': {
        'user': '40/minute',
        'anon': '20/minute' 
    }

From this example Unauthenticated users will only be able to make 20 requests per minute while authenticated users can make 40 requests per minute.

Add Throttling to a view

You pass a throttle class to the throttle_clasess attribute for class based views.

from  rest_framework.generics import ListAPIView
from blog.serializers import BlogSerializer
from rest_framework.throttling import UserRateThrottle

class Blogview(ListAPIView):  
    serializer_class = BlogSerializer
    throttle_classes = [UserRateThrottle]

In function based views use the throttle_classes decorator.

@api_view(['GET'])
@throttle_classes([UserRateThrottle])
def blog_view(request, format=None):
    content = {
        'status': 'request was permitted'
    }
    return Response(content)

Now for either of these views the authenticated users will be limited to only 40 requests per minute.

Custom throttling classes

You can use a throttles.py file in the app folder to write a custom throttling class for specific views as shown.

from rest_framework.throttling import UserRateThrottle

class BlogRateThrottle(UserRateThrottle):
    scope = 'blog'

You also need to update the _**settings.py**_ file to this.


REST_FRAMEWORK = {
    'DEFAULT_THROTTLE_CLASSES': [
        'rest_framework.throttling.UserRateThrottle',
        'rest_framework.throttling.AnonRateThrottle',
        'blog.throttles.BlogRateThrottle', #new line
    ],
    'DEFAULT_THROTTLE_RATES': {
        'user': '40/minute',
        'anon': '20/minute' ,
        'blog': '10/minute', #new line
    }
}

You can then add this custom throttle class to your view.

from  rest_framework.generics import ListAPIView
from blog.serializers import BlogSerializer
from .throttles import BlogRateThrottle

class BlogView(ListAPIView):  
    serializer_class = BlogSerializer
    throttle_classes = [BlogRateThrottle]

For this view only , authenticated users will now be limited to 10 requests per minute.

Throttling specific HTTP methods

In the example below only the post request in the viewset is throttled.

from  rest_framework import viewsets
from blog.serializers import BlogSerializer
from blog.models import Blog
from rest_framework.throttling import UserRateThrottle


class BlogViewSet(viewsets. ModelViewSet):
    queryset = Blog.objects.all()
    serializer_class = BlogSerializer

    def get_throttles (self):
        if self.action == 'create':
            throttle_classes = [UserRateThrottle]
        else:
            throttle_classes = []
        return [throttle() for throttle in throttle_classes]

Conclusion

API throttling is a cool and powerful feature , however you shouldn’t treat it as a security feature against brute forcing or denial-of-service attacks due to reasons like spoofing of IP origins.