How not to specify __typename when creating nested normalized local data

If I want to insert nested local data to be normalized, I need to specify both id and __typename all around my json, for all entrees. But this is time consuming and error prone (e.g. if I forget it for one entry, the store will mix normalized and non-normalized data):

const IS_LOGGED_IN = gql`
  query IsUserLoggedIn {
    isLoggedIn @client
    cake @client {
      name @client
      ingredients @client {
        name @client,
        quantity @client
      }
    }
  }
`;

client.writeQuery({
  query: IS_LOGGED_IN,
  data: {
      isLoggedIn: false,
      cake: [
          {id: "1", __typename:"Cake", name: "Cookies", ingredients: [
              {id: "4", __typename:"Ingredients", name: "Sugar", quantity: "100g"},
              {id: "5", __typename:"Ingredients", name: "Chocolate", quantity: "250g"}
          ]},
          {id: "2", __typename:"Cake", name: "Choux", ingredients: [
              {id: "6", __typename:"Ingredients", name: "Eggs", quantity: "2"},
              {id: "8", __typename:"Ingredients", name: "Flour", quantity: "250g"}
          ]},
      ]
  },
});

Is it possible somehow to exploit the local schema to infer automatically the type of the data, so that I don’t need to add it myself?

Hi @tobiasBora - welcome to the forum! Type policies will get you part of the way there:

const cache = new InMemoryCache({
  typePolicies: {
    Ingredients: {
      keyFields: ["name", "quantity"],
    },
  },
});

Assuming the combination of name and quantity is sufficient for differentiating one Ingredients object from another, this will remove the need to assign an id.

However, __typename is an essential part of normalization. You will still need to have objects with __typename: "Ingredients" in order for that type policy to work. If you find yourself duplicating a lot of __typename: "FooBar" expressions in your codebase, consider creating a utility function to reduce the amount of duplication. I hope that helps, let me know :pray:

Also I believe you may be asking a similar question in our Discord, cross-linking @lenz’s response for context:

I 100% agree with his response.

Thanks a lot for your answer, too bad apollo can’t deal with this better, especially when client schema could be used for this.

Regarding lenz answer that does not recommend Apollo client for local state management, I’m really confused now: using redux + normalizr seems much more complicated to maintain than graphql that I find to bequite elegant, especially when we addionally use graphql to deal with remote content anyway. So would you recommend redux + normalizr + appolo for instance in that scenario? If yes, what is wrong with appolo alone?