apollo-client
apollo-client copied to clipboard
Merge multiple caches for restoration
We're looking at micro-frontends with SSR support. Currently each MFE is rendering a part of the page in React, and extracting the data.
Is there a way to extract the InMemoryCache
for each MFE, merge them, then create a new single Apollo client on the client using this merged cache?
It looks like entityStore
might support this merging behaviour already (here) - but when cache.restore()
is called, the entity store is reset (here). If the entity store wasn't reset, would this handle the merging - or are there caveats to this?
Thank you for reporting this! I suggest posting this in our Apollo Community for guidance from other Apollo users, as other's may have input into your question. I'll also leave this open to see if the team has any insights as well.
As a temporary solution maybe you can try something like this :
const mergeApolloCache = (mainClient: ApolloClient<NormalizedCacheObject>, client: ApolloClient<NormalizedCacheObject>) => {
const newData = client.cache.extract();
if (newData) {
const currentStore: EntityStore = (mainClient.cache as any).data;
// Extract of cache.replace code without the clear old cache part
// https://github.com/apollographql/apollo-client/blob/83935e8e1ea2c3eb4a0f10fffbbfb4d51cfc02d2/src/cache/inmemory/entityStore.ts#L335
const { __META, ...rest } = newData;
Object.keys(rest).forEach(dataId => {
currentStore.merge(dataId, rest[dataId] as StoreObject);
});
if (__META) {
__META.extraRootIds.forEach(currentStore.retain, this);
}
}
};
I've tested a few cases and it seems to work fine.
I'm also a bit puzzled on how to have multiple services specifying their own cache configuration but having just 1 Apollo client for the whole application. It's not exactly MFE but it's lazy loaded modules which is basically almost the same thing at the end of the day.
Each lazy loaded module knows their cache policies but the root module doesn't. I can have an Apollo Client per lazy loaded module but then I would have to plug to the root Apollo Client cache somehow to be able to access root state like the logged in userId
for instance. I've been googling for the past hour and can't find anything obvious. Feeling pretty stupid right now, lol
The solution from @jgan42 works well - it's pretty much using the same code used internally for restoration