visit
When we're querying Kontent.ai using the Delivery REST API, there is an HTTP header we can use that instructs the API to only return fresh data. It's named X-KC-Wait-For-Loading-New-Content
.
X-KC-Wait-For-Loading-New-Content
Header// Set wait header in JavaScript
const client = KontentDelivery.createDeliveryClient({
projectId: '<PROJECT_ID>',
});
const response = await client.item('my_post')
.queryConfig({ waitForLoadingNewContent: true })
.toPromise();
Whereas the following example in .NET sets up the client as always waiting for fresh content:
// Set wait header in dotnet
IDeliveryClient client = DeliveryClientBuilder
.WithOptions(builder => builder
.WithProjectId("<PROJECT_ID>")
.UseProductionApi
.WaitForLoadingNewContent
.Build())
.Build();
IDeliveryItemResponse<Post> response = await client.GetItemAsync<Post>("my_post");
Overall, I prefer the JavaScript approach here, as it allows developers to be explicit about when the fresh content is important to our application. With the .NET approach, it feels a little like a sledgehammer and might cause us to think about registering multiple clients to get the best performance for our application.
A key thing to note is that, when the header is set, only the root items of the query are checked for freshness. Any linked items/modular content will not wait for stale content to be flushed.
In the above diagram, the root item in the query itself has not changed but the linked items have. When we request the root item and include the linked items, the delivery API will return a cached query response.
In my example, I have a Courses type that has Availability Slots as linked items. A scheduled job keeps my availability slots synchronised with an external service. When these slots are updated, I then create a denormalised view of my data in an Azure Cognitive Search index to allow users to search for courses. But, If I process my data too quickly relying on getting the course and its availability slots in a single query, then I run into problems.
To make sure I get the latest versions of the linked items, I request them at the root level of a query as follows: // in order to get the latest availability data, we need to request the slots directly
const availabilitySlots = await getClient()
.items()
.queryConfig({ waitForLoadingNewContent: true })
.inFilter(
'system.id',
course.availability.value.map((a: any) => a.system.id),
)
.toPromise()
.then((response) => response.items);
This promotes the course availability slots to the root of the query and waits for the updates to finish processing to make sure that the fresh data is returned.