_Disclaimer: not sure if doing something wrong and can't get it working or just not implemented.
To the point:_
I'd like to achieve caching on more granular level than just queries - caching fragments or even fields.
I'll use a simple example to introduce the problem:
Let's say we have the following query, defining data requirements for component Abc:
query BigQuery {
someType {
id
a
b
c
d
}
}
When I mount Abc, the request with BigQuery is sent and after a while I receive a response with data. But Abc is a big component (whole _view_ perhaps) and BigQuery takes long time to return all the necessary data. And so I want to preload some of it, to render the _critical path_ of the component. So I fire the following query beforehand:
query PreloadedData {
someType {
id
b
c
}
}
Now after PreloadedData is processed, I see b and c in the redux store of Apollo. When it comes to fire BigQuery afterwards, I notice in devtools that Apollo asks not only for the remaining: a and d, but also for b and c, even though it's already in store.
I tried to use fragment like this, but it changed nothing:
fragment Preload on SomeType {
id
b
c
}
query BigQuery {
someType {
...Preload
a
d
}
}
query PreloadedData {
someType {
...Preload
}
}
Maybe customResolvers are the way to go, to hint Apollo how to resolve types?
If I haven't mixed something up or missed a part from docs, my suggested solution would be to check the store in search for already downloaded fields and exclude them from the query and/or cache fragments in the same way as whole queries.
We intentionally don't modify the queries in any way before sending them to the server. If you put { a, b, c, d } in the query, either nothing is fetched, or the whole query, every time.
This is because it would be easy to end up with inconsistencies between the fields if they were fetched at a different time.
If you want the behavior above, I'd suggest using multiple queries.
@stubailo Haven't Apollo's team consider such caching strategy as an option? It opens the door to more declarative query<->component connections, where more granular queries are assigned to smaller components and prefetching is easier due to the data updates being handled behind the stage, in Apollo internals. This would also mean better encapsulation end reusability of components.
_EDITL:_ Or event better - the above mentioned per-graphbranch caching (in comparison with per-query caching like now is implemented in Apollo, as I understand) could be the default mode and opting out from this mode (= fetching the whole query independently of what is already in store) could be done based on some additional option to the query() method. Thus the enhanced declarativity would be achieved out-of-the-box, but still super-easy to turn off.
Do you think that could work, is it event possible? The idea is something that my team would like to work with, a result of mind-storming and experience with hooking up Apollo into a big project.
This issue has been automatically marked as stale becuase it has not had recent activity. It will be closed if not further activity occurs. Thank you for your contributions to React Apollo!
This issue has been automatically labled because it has not had recent activity. If you have not received a response from anyone, please mention the repository maintainer (most likely @jbaxleyiii). It will be closed if no further activity occurs. Thank you for your contributions to React Apollo!
@stubailo @helfer @calebmer @jbaxleyiii @Poincare It is clearly stated in this article (y. 2016): https://dev-blog.apollodata.com/the-concepts-of-graphql-bc68bd819be3 that Apollo implements per-field caching. It says, that if I send two completely different queries having the same item in them, the item in the second query will be omitted:
(...) the second query doesn鈥檛 need to go to the server to get the name of the author. This information can just be found within the cache from the result of the previous query.
Apollo Client uses this kind of logic to remove parts of the query based on the data already in the cache.
So what has changed since 2016 that Apollo doesn't do that any more? Or maybe there is some way to enable it after all?
So what has changed since 2016 that Apollo doesn't do that any more?
We intentionally removed this feature in 0.5: https://github.com/apollographql/apollo-client/blob/master/CHANGELOG.md#v050-0-first-preview
Feature removal: Remove query diffing functionality to make client more predictable and simplify implementation. Queries will still read from the store, and if the store does not have all of the necessary data the entire query will fetch from the server. Read justification and discussion in Issue https://github.com/apollographql/apollo-client/issues/615 PR https://github.com/apollographql/apollo-client/pull/693
For more info check this article which explains some of the reasoning: https://dev-blog.apollodata.com/5-benefits-of-static-graphql-queries-b7fa90b0b69a