Skip to content
This repository has been archived by the owner on Apr 13, 2023. It is now read-only.

Caching fragments / single fields #792

Closed
jalooc opened this issue Jun 19, 2017 · 6 comments
Closed

Caching fragments / single fields #792

jalooc opened this issue Jun 19, 2017 · 6 comments

Comments

@jalooc
Copy link

jalooc commented Jun 19, 2017

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.

@stubailo
Copy link
Contributor

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.

@jalooc
Copy link
Author

jalooc commented Jun 20, 2017

@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.

@stale stale bot added the wontfix label Jul 5, 2017
@stale
Copy link

stale bot commented Jul 5, 2017

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!

@settings settings bot removed the wontfix label Jul 8, 2017
@stale
Copy link

stale bot commented Jul 29, 2017

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!

@jalooc
Copy link
Author

jalooc commented Aug 17, 2017

@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’t 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?

@stubailo
Copy link
Contributor

stubailo commented Aug 17, 2017

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 apollographql/apollo-client#615 PR apollographql/apollo-client#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

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants