Keep your cached content up to date
Once you’ve picked your caching strategy, handling cache dependencies becomes crucial.That way you always know which part of your cache to invalidate when something in your Kontent.ai project changes.
Cache implementation 101
Let's go through the general process of storing API responses in your app's cache. The following sample scenario assumes a web application that powers a blog site. The site can show a list of blog posts, display a specific blog post, and organize posts by tags. With Kontent.ai, each blog post is a content item, and each tag is a taxonomy term.Step 1: Define your app’s business layer
It's a good practice to define specific custom actions within your app (such as retrieving a blog post) and rely on those custom actions in your app. Think about the actions that your app performs regularly and create methods for them. Using the blog site example, these actions can be:- Get a blog post
- Get a list of blog posts
- Get a list of blog posts by category
// Without custom actions, you use the Delivery client directly, specifying its parameters each time.
Client = DeliveryClient("<YOUR_PROJECT_ID>")
response = Client.items()
.type("<type_codename>")
.limit(10)
.skip(20)
// With custom actions, you use named action to perform business logic.
// GetPost action retrieves a blog post by its codename.
GetPost("<post_codename>")
// GetPosts action retrieves a list of blog posts and provides paging.
GetPosts( <skip>, <limit>)
// GetPostsByCategory action retrieves a list of blog posts tagged with a specific category, and provides paging.
GetPostsByCategory("<category_codename>", <skip>, <limit>)
Step 2: Implement logic for caching your content
When you retrieve a blog post using your customGetPost()
action, you get a JSON response with the specified blog post. Whenever you get a response from the API, you store the response in the cache.
To cache the response, create a cache entry that uses a naming pattern such as <action_name>|<action_parameters>
for its key. Use this pattern to uniquely identify the responses within the cache for each of your custom actions.
For example, if you retrieve a blog post named My blog post, you name the cache entry key for the response GetPost|my_blog_post
. You can adjust the pattern to suit your needs and naming conventions.
Once you put the response in the cache, you're done. The next time your app calls GetPost("my_blog_post")
, it retrieves the blog post from the cache without having to make any request to the API.
Handle cache dependencies
If fresh content is important to you, correct cache dependency handling is crucial. Let's see how to identify the cache dependencies and store them in the cache. Imagine your app requests a blog post and gets an API response with several components and a few links to content items. The linked items are dependencies of the blog post. If the dependencies change, so does the blog post. The structure of the API response looks similar to the simplified JSON below.- In the
item
object, you find a content item representing the blog post itself. - In the
modular_content
object property, you find the components and linked items as separate object properties.
<object_type>:<object_codename>
. Using the content item from the simplified JSON, the dependency name would be item:guest_blog_post
. This way, you can invalidate the correct dependencies whenever there’s a change in your content items.
{
"item": {
"system": {
"id": "f4b3fc05-e988-4dae-9ac1-a94aba566474",
"name": "My blog post",
"codename": "my_blog_post",
"language": "default",
"type": "blog_post",
"sitemap_locations": [],
"last_modified": "2022-10-20T12:03:48.4628352Z"
},
"elements": { ... }
},
"modular_content": {
"guest_blog_post": {
"system": { ... },
"elements": { ... }
},
"n2dfcbed2_d7a1_0183_4324_a2282f735f48": {
"system": { ... },
"elements": { ... }
}
}
}
Differentiate content items from components
When you get content items from Delivery API, themodular_content
object in the API response contains both content items and components. Structurally, components and content items look the same.
To tell content items and components apart, find the object’s ID and check the third group of characters in the ID.
- If the characters do NOT start with 01, for example, ce0288e7-294c-46e5-b9bc-b086656d5c48, it's a content item.
- If the characters start with 01, for example, ce0288e7-294c-01e5-b9bc-b086656d5c48, it's a component.
Guidelines on creating cache dependencies
Use the following guidelines for constructing your app’s cache dependency logic. For a Delivery API response with:- Single content item
- If the number of objects in the
modular_content
object property is below 30, add cache dependencies for all the objects. - If the
modular_content
property contains too many objects to define as separate dependencies, add a special general dependency for any content item. In such case, your app invalidates the cached response whenever any other content item is invalidated.
- If the number of objects in the
- List of content items – Add cache dependencies for all the content items in the list.
- Single taxonomy group – Add a cache dependency for the taxonomy group object returned in the response.
- List of taxonomy groups – Add a cache dependency for all the taxonomy groups in the list.
Guidelines on invalidating cache dependencies
Sign in with your Kontent.ai credentials or sign up for free to unlock the full lesson, track your progress, and access exclusive expert insights and tips!