In the docs for merging non-normalized objects, the ‘author’ field is unique by name. What about a case where we do not have a unique field, and not even any unique composition of fields? Take this example:
[EDIT: Changed query names and parent object to hopefully make more sense. We’d expect these to be the same list of drinks.]
query DrinksInInventoryLocation {
warehouse {
id
drinks {
name
storageShelf
}
}
}
query DrinksInInventoryConditions {
warehouse {
id
drinks {
name
conditionOfCan
}
}
}
Assume these are used by different components, and so one would clobber the other in the cache. Order is not guaranteed. For the first query we could have results like (leaving off the Warehouse):
{ drinks: [
{ name: "Coke", storageShelf: "B" },
{ name: "Coke", storageShelf: "B" },
{ name: "Coke", storageShelf: "C" },
{ name: "Pepsi", storageShelf: "C" }
] }
and for the second:
{ drinks: [
{ name: "Coke", conditionOfCan: "poor" },
{ name: "Coke", conditionOfCan: "fair" },
{ name: "Coke", conditionOfCan: "good" },
{ name: "Pepsi", conditionOfCan: "good" }
] }
What is the best practice in this case, especially if there are many old queries that need to be migrated? In many cases it makes sense to require some kind of ID or other unique key (it’s somewhat difficult to think of legitimate counter examples), but we have older queries/types that don’t always have this available. These are cases that were “working” fine with the path/index-based caching of Apollo v2 (even though that wasn’t always safe or quite correct).
We’ve added IDs where we can, and we’ve also added fragments (so in this example the fragment would include name, conditionOfCan, and storageShelf and you’d include it in both queries) for cases like this. (The latter risks getting out of sync if somebody adds a field to one query and not the fragment.)