question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

[Feature request] partial cache matches

See original GitHub issue

Use Case

Currently, when Apollo doesn’t find a complete cache match for a query, it fetches the entire query via the given ApolloLink. I’d like to set up a system whereby I can retrieve a partial match from the cache and only fetch any missing data.

Could this be a plugin?

I think we could facilitate a plugin for this in one of 2 ways:

  1. some sort of middleware for hooking into the query handling (i.e. should it be fetched from cache or from a link, etc.)

  2. Give the link access to the client / cache object

Is there a workaround?

It seems there might be. If I create the cache first, then make a function linkWithCache<T>(cache: ApolloCache<T>): ApolloLink, I may be able to access the cache within the link via a closure.

Thoughts?

Thoughts from the Apollo team would be much appreciated here, re: what the best approach would be.

Issue Analytics

  • State:closed
  • Created 6 years ago
  • Reactions:12
  • Comments:5 (4 by maintainers)

github_iconTop GitHub Comments

5reactions
jonaskellocommented, Apr 18, 2018

To give a concrete example where I think cache-diffing would be useful. We have a lot of product data that is published in versions. Each published version is immutable and this is what the client application reads. So the client application can be sure that the server-side product data never changes. However, performance is critical so we want to read just the amount of data we need from the server and also minimise roundtrips.

So lets say I have this query:

query GetProductData($selectedProducts: [ID!]) {
  allProducts: products {
    id
    name 
  }
  selectedProducts: productsByIds(ids: $selectedProducts) {
    id
    name
    foo {
      bar1
      bar2 {
       zoo1
      ... a lot of other fields ...
     }
  } 

This query is used for a view where there is a list of products fed from allProducts field, and also a detailed product view where the user can add products from the list. The detailed view requires the data in the selectedProducts field.

Now when I run this the first time I get all data at once which is good. Then when the user picks a product, the $selectedProducts variable changes and the query is re-fetched. Unfortunately the allProducts field is also refetched now. Ideally it would come from cache and instead only the selectedProducts field would be fetched. Actually this is the way I thought apollo would work.

The only other option I can see is to break the query into multiple queries. Now reality is not as simple as the example above, so I would end up with a lot of small queries, which would mean a lot of round-trips, which will kill performance. Sure you could batch some queries, and if you are lucky with the timing you will decrease the round-trips, but that is more of a work-around than a solution by design.

So my question here would be what disadvantages cache-diffing would have for this kind of application?

5reactions
jonaskellocommented, Apr 18, 2018

IIRC, one of the design goals of GraphQL itself is to minimise roundtrips (in contrast to REST where the design lends itself to many roundtrips). Considering that, I think apollo should at least allow for this option even if it would not be the default.

I can see how cache-diffing could cause problems for some project, but in others I think it would be very helpful. So I am a bit surprised that apollo does not support this.

@Poincare perhaps you could elaborate on " this makes reasoning about missing data and reactivity significantly more complicated"?

Read more comments on GitHub >

github_iconTop Results From Across the Web

CacheStorage.match() - Web APIs - MDN Web Docs
The match() method of the CacheStorage interface checks if a given Request or URL string is a key for a stored Response.
Read more >
Request matches - Akamai TechDocs
This match type allows for application of metadata based on the method used in the request ( GET , POST , HEAD and...
Read more >
Complete Cache Fill (End-of-Life)
A partial cache miss typically occurs after a user aborts a download or for assets that are solely requested using HTTP range requests....
Read more >
2 Caching Concepts
Validation works by the comparing two validators, one in the request header and the other in the cached object's response header, to determine...
Read more >
RFC 2616: Hypertext Transfer Protocol -- HTTP/1.1
A feature of HTTP is the typing and negotiation of data representation, ... The semantics of the GET method change to a "partial...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found