I would like apollo to stop using cached/merged versions of a particular subdocument.
TLDR: when I have a document with a __typename
and _id
that has another subdocument with a __typename
and _id
, Apollo is updating the subdocument when it receives another version of the main document. I’ve been reading the docs all day but can’t figure out how to do something simple like
const typePolicies = {
User: {
fields: {
position: "do not cache me ever"
}
}
}
Full story:
Suppose I have a system with objects like
Users
- name
Positions
- authorization level
- title
Groups
- users
Every user
inside a group
has a position
, and that position
is specific to that group + user
, not a user
in general. ie a regular user
object has no position
.
When I make a graphql query, I might get something like this on the wire
{
groups: [
{
__typeName: 'Group',
_id: 'abc1',
name: 'Group A',
users: [
{
__typeName: 'User',
_id: 'abc2',
name: 'Jim Bob',
position: {
__typeName: 'Position',
_id: 'abc2',
level: 1,
title: 'Teacher',
},
},
],
},
{
__typeName: 'Group',
_id: 'def1',
name: 'Group B',
users: [
{
__typeName: 'User',
_id: 'abc2',
name: 'Jim Bob',
position: {
__typeName: 'Position',
_id: 'def3',
level: 5,
title: 'Master',
},
},
],
},
];
}
But when I console log things after Apollo has done its magic, user Jim Bob
gets his position
overwritten with the second position
object. Now in all groups he is a Master
instead of being the specific position for each group.
Now I’ve been looking into ApolloClient
’s InMemoryCache
options and tried this
// Just use whatever comes on the wire.. ?
const nomerge = (existing, incoming) => {
return typeof existing === 'undefined' ? incoming : existing;
};
const cache = new InMemoryCache({
User: {
fields: {
position: {
merge: nomerge,
},
},
},
}),
But it doesn’t really do anything. I can put a log in nomerge
and see that it runs, but surprisingly, it only ever logs once even though I have many many groups with the same user.
Now I did have success doing this, but it’s a hack and I’m not sure how it will affect the rest of the system.
const cache = new InMemoryCache({
User: {
fields: {
position: {
read(_, { args, cache, toReference }) {
return toReference({
__typename: 'Position',
id: args?.id,
});
}
},
},
},
}),
At the end of the day, all I want is Position
inside of User
to not be cached in any way. Just give me what’s on the wire.