How to cache API Endpoints

2020-03-03

Supreme image

When developing advanced web software you don't want the user to hit the database if it's not necessary.

Terminology: DJRF - Django Rest Framework

To avoid database requests and make your app faster you should start using some kind of cache strategy. One of the strategies that I've been using is as follows:

  1. A worker that runs every 5 min caches/recaches some DJRF Views

  2. End User hits the view that returns the cached object.

To achieve this, I've written two classes:

  1. CacheHelperSet()

Objective: Used to save a object to cache

  1. 2. CacheHelperListView()

Objective: Helper method to retrieve cached data

CacheHelperSet()

Pythonclass CacheHelperSet():
    def cache_view(self, view):
        queryset = view.get_queryset()
        serializer_class = view.get_serializer_class()
        cache_key = view.cache_key

        serializer = serializer_class(queryset, many=True)
        cache.set(cache_key, serializer.data)

    def cache_views(self, views):
        for view in views:
            print 'Caching: ', view.get_view_name()
            self.cache_view(view)

The class consists of 2 methods: cache_view (singular) and cache_views (plural). As you might have guessed the former takes a single DJRF GenericView as its input and the latter takes an array of DJRF Generic Views.

You can easily use this class to cache the result of your DJRF Generic Views. Lets say you have a couple of views and you want to create a management command (run by a crontab) to cache the serialized object returned by the view.

Pythonfrom django.core.management.base import NoArgsCommand
from django.core.cache import cache

from cachehelper import CacheHelperSet

from myapp.views import MyView1, MyView2, MyView3


class Command(NoArgsCommand):
    def handle_noargs(self, **options):
        views = [
            MyView1,
            MyView2,
            MyView3
        ]

        chs = CacheHelperSet()
        chs.cache_views(views)

That's it. You have now cached the serialized object that the endpoint is supposed to return!