Optimal Cache strategy

Hi all,

I am working on a project where our queries are all seperated per concern. For example we have a kpi, for the kpi we have a query kpiDetails and another query kpiRelatedReports and kpiSpecifics. In our backend these are all stored under kpi. For performance reasons we seperated them in the frontend, since we don’t need all the data at the same time. However our mutations are single, so we have a createKpi, updateKpi and deleteKpi to edit everything on the kpi field. What would be the best caching strategy in my situation for updating the cache without having to do a whole lot of checks of which query should be updated. The end goal would be that I could keep the cache for all the 3 queries together under kpi. Any suggestions or remarks?

Thanks in advance,
Brecht

The Apollo cache is normalized, so every object with an id and a __typename will only be stored in the cache once and referenced throughout the cached queries. In your example, after calling each of your three queries, your cache might look like this:

{
    ROOT_QUERY: {
        __typename: 'Query',
        kpiDetails: [{
            __ref: 'Kpi:123'
        }, {
            __ref: 'Kpi:456'
        }],
        kpiRelatedReports: [{
            __ref: 'Kpi:123'
        }, {
            __ref: 'Kpi:456'
        }],
        kpiSpecifics: [{
            __ref: 'Kpi:123'
        }, {
            __ref: 'Kpi:456'
        }],
    },
    'Kpi:123': {
        __typename: 'Kpi',
        id: '123',
        someField: 'someValue'
    },
    'Kpi:456': {
        __typename: 'Kpi',
        id: '456',
        someField: 'someOtherValue'
    }
}

In the case of updateKpi, Apollo will conveniently take care of the cache updates for you, if the mutation returns the id and __typename of an object that’s already present in the cache. When calling createKpi, you will have to manually add the new Kpi to each of the root queries in the cache using cache.modify, because Apollo can’t know which ones you would want to add it to. And for deleteKpi, you can simply use cache.evict, which will automatically remove the evicted object’s references from every array in the cache.

So in summary, deciding which root queries a new item needs to be added to is something you’ll unfortunately have to do if you wish to use the cache. If it’s just these three queries that need updating, it’s perfectly maintainable, though. If you end up with parameterized queries, things could become a lot trickier, but it can still be done. I’ve recently written a lengthy guide on cache manipulation - you can have a read through to gain a better understanding on how the cache works and how best to keep it updated: apollo-augmented-hooks/CACHING.md at master · appmotion/apollo-augmented-hooks · GitHub

1 Like

Thank you for your reply! I will definitely read your blog.