Django, What does it mean to cache an endpoint?

Viewed 324

with DRF or with plain view, I use something like this.

@method_decorator(cache_page(60))
def list(self, request, *args, **kwargs):

How does cache works?

When a user-a requests it, it caches for 60 seconds.
When a user-b requests the same endpoint, it returns the cached response

After 60 seconds, cache expires purely because time has passed. (it doesn't matter what happened during the 60 seconds)

And the 60-seconds cycle begins when another user requests the same end point?

2 Answers

In basic term, cache_page is a decorator which can cache the view's response. So,

And the 60-seconds cycle begins when another user requests the same end point?

yes. View will be return cached response for any request for 60 seconds.

Let's assume that we have a view like /api/foo/ that use cache_page and we make get request to that view. Before the request;

In [1]: cache.keys("*")
Out[1]: []

we do not have any cached value. Perform first get request and then;

In [2]: cache.keys("*")
Out[2]: 
['views.decorators.cache.cache_header..883916f71c4da1b141ca1ff4dc7019a5.en.Europe/Istanbul',
 'views.decorators.cache.cache_page..GET.883916f71c4da1b141ca1ff4dc7019a5.05ef8c85ad5bfa657724f2753311c056.en.Europe/Istanbul']

we have cached response. After the first request, all requests will get the same response for 60 seconds.

But, I do not recommend to use that decorator for caching. Because, even if you do not use query parameters, it will be store new cache value for any requests like; /api/foo/?a=1, /api/foo/?x=y, /api/foo/?asdasd

In [7]: cache.keys("*")
Out[7]: 
['views.decorators.cache.cache_header..883916f71c4da1b141ca1ff4dc7019a5.en.Europe/Istanbul',
 'views.decorators.cache.cache_header..e9c29669e862c476759c45b12ada4cbc.en.Europe/Istanbul',
 'views.decorators.cache.cache_page..GET.0ab7d958193472928e5601220fd320a2.05ef8c85ad5bfa657724f2753311c056.en.Europe/Istanbul',
 'views.decorators.cache.cache_header..46a68ec3d6f1ab223d7b2dd5916f2de3.en.Europe/Istanbul',
 'views.decorators.cache.cache_header..0ab7d958193472928e5601220fd320a2.en.Europe/Istanbul',
 'views.decorators.cache.cache_page..GET.e9c29669e862c476759c45b12ada4cbc.05ef8c85ad5bfa657724f2753311c056.en.Europe/Istanbul',
 'views.decorators.cache.cache_page..GET.46a68ec3d6f1ab223d7b2dd5916f2de3.05ef8c85ad5bfa657724f2753311c056.en.Europe/Istanbul',
 'views.decorators.cache.cache_page..GET.883916f71c4da1b141ca1ff4dc7019a5.05ef8c85ad5bfa657724f2753311c056.en.Europe/Istanbul']

as a result, cache your method instead of using cache_page. For example;

class MyService:
    def _read_from_cache(self, key):
        return cache.get(key)

    def _write_to_cache(self, key, value, ttl=60 * 1):
        cache.set(key, value, ttl)
        
    def my_method(self):
        cache_key = "my_cache_key"
        cache_value = self._read_from_cache(key=cache_key)
        if cache_value:
            return cache_value
        context = {"hello": "world"}
        self._write_to_cache(key=cache_key, value=context)
        return context

and in views.py;

def list(self, request, *args, **kwargs):
    service = MyService()
    context = service.my_method()
    return Response(context)

Yes. When cache is set, it holds the value until time has passed, or until you explicitly delete/overwrite it.

When request is received, django will:

  • check for cached response
  • if cached - return cached value, do not execute method
  • else execute method, return response and set cache

Since cache is set on request, whoever sends the same request in the next 60 seconds will receive same response, even though some values/objects might change in the meantime.

You shoud be careful with caching responses - if some data/object is updated each second, caching response for a minute is probably not a good idea (of course it highly depends on the use case).

Here's a link to the documentation.

Related