Cache Context Drupal 8 — Part 1

Hello everyone! We all know that Drupal 8 has very slick cache api as compared to the Drupal 7. We can now invalidate exactly what we want (AFAIK) instead of all (as in Drupal 7). Example is when we save/update any node in Drupal 7, it clears all the cached data in that bin irrespective of relevancy or not but that’s not the case in Drupal 8. The exact cache clear in Drupal 8 is done by cacheability metadata(cache-tags, max-age and cache-contexts). We will discuss about cache context in this post?

In my recent project, I got a chance to work with (actually look into) cache context. I already had some (basic) knowledge about cache context and what I found out that cache context is still an unrevealed topic for Drupal developers and so I thought of writing whatever I know about cache context.

So what is cache-context? Well cache context is something which allows caching of different variation of something (example content or result of some complex, long time/resource taking computation). Cache context is similar to HTTP-Vary header (cache variations). As per D.O definition

“Cache contexts provide a declarative way to create context-dependent variations of something that needs to be cached.”

What I found out during cache context lookup that cache context is a global thing. By global means any info available or can be get on every request like user info, IP, session etc. If something is not global or can’t be determine in every request, we can’t use that for cache context(again AFAIK). One example is like node info or node field info. We can’t have/get info about a node on every request and thus this can’t be used as cache context (again AFAIK) on the other hand let’s take example of user. We have user info available globally (for each request) and thus we can use that in cache context. Similarly session, cookie, IP are something which we have on every request and thus can be used for cache context.

You can find the available cache context list in core here

Let’s discuss the use case of cache context. A client wants to show the role of the current user in a block. For simplicity we assume that single role can be assigned to user (except authenticated role). In Drupal 7, this can be easily done. But client also wants the proper caching :). This is tricky thing. In Drupal 7, we have page level and block level caching. Page level caching only works for anonymous users, so block level caching is our only pick but problem with block level caching is that it doesn’t provide variation. It will cache the block for first user visit and show the same data to other(no caring if user has different roles).

Drupal 8 has in-built solution for the above problem (cache context :)). Drupal 8 core provides the user.roles cache context which allows the cache variation based on user roles. So if a user with role ‘A’ comes up first time, block will be cached. Second time if same/different user with role ‘A’ comes, cached version of block will be served. If another user with role ‘B’ comes up, then un-cached version of the block is served. Second time for user with role ‘B’, cached version of the block will be used.

Can we create custom/new cache context ? Yes we can. We will create a custom cache context in next post.

If you want more info about cache context in Drupal 8 as this blog only contains just what I know, please visit D.O.