Open ValentinH opened 5 months ago
Hey @ValentinH π
Thanks for opening the request and thanks for your patience!
This is an interesting idea, though I'd like to push back a little bit on the idea of a document-based solution. Since InMemoryCache
is a normalized cache, there are scenarios that get tricky to handle. For example, what happens if you issue 2 queries that request the same field and you only invalidate one of the queries? Does it partially invalidate the other query? Should it refetch the other query because its partially invalidated? Those are things to think through as well.
I do agree with you that there should be a more robust invalidation API, but I'd prefer to use it on the field-level which fits the normalized cache paradigm more closely. In this case, invalidating a field would mark it as stale and any queries that consume that field would refetch in order to synchronize it with the server. Ideally this becomes the replacement for refetchQueries
in the future.
On the TypeScript end, I'd like to see InMemoryCache
accept a Schema
generic type that has full knowledge of your GraphQL schema types in order to better type APIs such as type policies, cache eviction, etc. We are hoping to get something like this either in 4.0 or a minor version shortly after. I'm hoping this would alleviate some of the type safety issues that currently exist when using the cache.
Thanks for the detailed answer.
I like the idea of field level invalidation, I'm looking forward to hearing more about it.
First, the issue I'm trying to address with this feature request was perfectly stated in 2016 in this comment:
Today, when we have a mutation that is affecting the result of a query done on another page, I'm using one of these approach:
fetchPolicy
tocache-and-network
: not ideal because you are over-fetching most of the timerefetchQueries
on the mutation: not ideal either for the reasons mentioned in #419 + because when using different set of variables (like when doing pagination), it only refetched that most recently used set of variables. In addition, sometimes we just don't want to refetch because the user might not go back to the query page so it could also be over-fetching.updateQuery
from the query and manually update the cache: most performant way to do it but it sometimes super hard or even impossible if the query is reading from an aggregation table for example.What I'm looking for is a way to invalidate a set of queries similar to react-query invalidateQueries.
I started to use
cache.evict({ fieldName: 'example' })
but the issue is that thefieldName
isn't type-safe. Therefore, I built this helper function to do this in a safe way from an array ofDocumentNode
(generated bygraphql-codegen
):I can then use it like this:
This is working fine on the tests I did but now I'm wondering if
cache.evict()
could directly accept aDocumentNode
(or even an array of nodes) toevict
all the fields selected by the queries (this comment was also suggesting this).Basically being able to do:
or to be even closer to
react-query
: