apollo-feature-requests
apollo-feature-requests copied to clipboard
Fine grained control of the staleness of a query - `cache-first`
Problem
Suppose there are query and variable combinations that occur quite frequently, and also swap between active and inactive states very often. The related data does not change very often, if at all. In these kinds of cases I might want to use the fetch policy cache-first so that I only make a network request if the value is not yet cached.
However, the data can occasionally change outside of the control of the client. For example, a new user is added or a product description changes. If I use the cache-first policy and never mutate the data myself, then the client will never see the latest state. This can be especially problematic for long lived user sessions that could last for hours or potentially more.
Current Solution
Assuming that it is not acceptable to tell users that they need to refresh the session, I believe that the current solution available is to call resetStore at some regularly interval, which will invalidate the cache and refetch all active queries. Alternatively accept the overhead of making many unnecessary requests.
Feature Request
Allow users to specify a staleTime for cache-first queries, which is an integer repersenting time in milliseconds.
This is a distinct concept from setting a poll interval. If a cache-first query is active, stays active, and there is a valid staleTime, then it will never refetch the result.
To avoid a breaking change, staleTime can default to Infinity or undefined.
If staleTime is a valid integer, then if the cached value is older than the staleTime when the query becomes active, then a network request will be made - not dissimilar to the behaviour of cache-and-network. Effectively this is a kind of middle ground between cache-first and cache-and-network, but with fine grained control over which policy to use by the user.
Prior Art
This is a feature that is supported by react-query where the concept of "stale" cache is prominent. For react-query staleTime defaults to 0, so all queries are by default "stale" immediately after fetch.
+1
Hey @m-rutter 👋
This is a really interesting idea!
One of the wrinkles with Apollo's cache is that its normalized, so its possible your app could have overlapping data between two queries. React Query does not support normalized caching, so the invalidation strategy is a bit easier to reason about.
If we support a feature like this, we'd need to account for collisions between 2 queries that differ in their "staleness" but share the same data.
Thanks a bunch for the idea!
@jerelmiller goodness forgot that I made this feature request.
Yes, at the time I wrote this I didn't really appreciate the normalised nature of the cache and the complexity it introduces to this kind of feature.
I do think it's still a problem that cache-and-network is a little overeager for some use cases, and there isn't really an option somewhere between it and cache-first.
Hey @m-rutter totally fine! I happened to be looking through this repo and figured I'd try and comment on some issues where I could 😄. I'd definitely love to hear some ideas you have on the cache-and-network side of things if you have them! Feel free to open a new issue with ideas specific to that if you'd like to share!
Given your comment:
at the time I wrote this I didn't really appreciate the normalised nature of the cache
do you think this feature request makes much sense? I'd be happy to close if this doesn't seem interesting or useful anymore. Let me know!