Prevent caching of subdocuments/specific types

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.