apollographql / apollo-feature-requests

πŸ§‘β€πŸš€ Apollo Client Feature Requests | (no πŸ› please).
Other
130 stars 7 forks source link

Automatically infer `__typename` for local data #398

Open tobiasBora opened 1 year ago

tobiasBora commented 1 year ago

When dealing with local data that I want to normalize, one needs to add __typename and id to all elements (if I forget it in one element, this element in not normalized), giving something like:

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"}
          ]},
      ]
  },
});

While ID can be automatically assigned using keyFields, __typename is mandatory. However, it would be great to automatically generate them, for instance using the client-side schema. If parsing the client-side schema adds too much dependency (but I don’t really understand why it is easy to parse queries like IS_LOGGED_IN but not a client-side schema), I can think of other alternatives:

  1. parse the schema at compile time and only bundle the parsed version in json
  2. or just ask the user to provide it in json or via an object (this is the choice made by the (now unmaintained) normalizr library). For instance, this could give:
    graphQLTypes = {
    Query: {
    isLoggedIn: "boolean",
    cake: "Cake",
    },
    Cake: {
    name: "string",
    ingredients: ["Ingredients"],
    },
    Ingredients {
    name: "string",
    quantity: "string",
    }

    From this, writeQuery could automatically add __typename, it even seems quite simple to do.

Related discussions: https://discord.com/channels/1022972389463687228/1145119756379226192