Caching when selection sets are involved #2745
Replies: 1 comment
-
I came across this post when trying to solve the exact same issue. Luckily for us, we have full control over the clients and at any given points there is only a handful (<5) query "variants" that the cache needs to store. So there is not a lot of redundancy. I do want to point out that building the cache key from the selection set might not be enough. You might also want to make other variables part of the key. Here is an example that would otherwise break: query MyQuery ($width: Int!) {
movie(id: "123") {
name
thumbnailUrl(width: $width)
}
} {
"width": 400
} So here, if you cache the movie object based on the ID The solution is to calculate a hash from both the selection set AND the variables. If the variables contain the ID as well it doesn't really matter, it will just be "represented" in the cache twice. This solution works for any other "dependent inputs" such as locale or time zone. Just make them part of the cache key. |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
I'm using graphql-java's batching and caching to make my API more efficient, however I've run into a problem that goes something like this:
Say I fetch a fruit object that has some attributes like "id", "name", "type", "weight", and "age". When I make a query like:
Fruit(id: "some-id") {
id
name
type
}
I will get the data back from a database, and it will cache the fruit with that id - and store the name and type of the fruit. The problem is, if I make another query for that id's fruit but this time with weight and/or age, the batch loader will see that id has a cache entry and returned what's stored there - but it doesn't have the weight or age. We end up with missing data because of the caching.
Of course, ultimately what we need is the right cache keys. Clearly the fruit ID, despite being a globally unique identifier for fruits, won't be sufficient for this.
What might work is combining the ID with the selected fields and creating a hash - however, this only works for exact matches of selection sets, not to mention that many large + nearly identical selection sets for an ID will result in a lot of redundant data storage. If we're querying for a subset of the cached fields, it will also be fine to fetch from the cache - but creating cache keys to handle all this seems extremely difficult.
It's important to note that the real domain I'm working in has large volumes of data, so simply fetching/caching the entire object with all the fields will be too slow - we need to dynamically construct our database queries based on the client's selection set.
Does graphql-java have a way around this? I'm a bit surprised there isn't more discussion - I'd have thought it's a very common issue specific to graphql, caching with different selection sets for a given object + handling subsets of a cached selection set.
We have a workaround in mind involving local context objects, but it's a bit messy and will only get more so as we add features and scale in the future.
Beta Was this translation helpful? Give feedback.
All reactions