Non-normalised objects (ie no ID) are overwritten by the Apollo Client cache
By default, the Apollo client cache overwrites non-normalised objects; ie, objects with no id. Generally, JSONB fields do not have ids and, in most cases, it would be better to merge incoming objects with cached objects.
Merging of non-normalised objects can be configured using "typePolicies". See: https://www.apollographql.com/docs/react/caching/cache-field-behavior/#the-merge-function
Eg, to configure JSONB merging in the Apollo cache, define the "makeApolloConfig" function and then pass it to the React "Root":
const makeApolloConfig = config => {
// Common logic for merging graphql properties which h
const mergeConflicts = (existing, incoming, { mergeObjects }) => {
return mergeObjects(existing, incoming)
}
// ASSUMPTION:
// The merge policy applies to ALL nested objects...
merge(config.cache.policies.typePolicies, {
Book: {
fields: {
// NB: docs suggest { merge: true } but this throws an error
metadata: { merge: mergeConflicts},
settings: { merge: mergeConflicts },
},
},
})
return config
}
ReactDOM.render(
<Root
history={history}
makeApolloConfig={makeApolloConfig}
routes={routes}
theme={theme}
/>,
rootEl,
)
This approach is OK but it would be better for Coko client to automatically identify non-nomalised objects and make merge the default behaviour. In the rare cases where merge is the wrong choice, some sort of merge blacklist could be configured.
Possible options for automatically detecting non-normalised objects:
- Walk the graphql tree and return all types with no id.
Issues:
- paginated results have no id and it might not make sense to cache them. If they should be cached, then perhaps the client should specify an id for the results...
- Walk the models tree and identify all JSONB fields then autogenerate the type policies code.
Issues:
- This still requires manual intervention; run a script and copy paste the output.