New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Response Cache should allow cache invalidation based on Operation typename and input variables #3125
Comments
Hi, thank you for your proposal, this is very interesting! We are currently thinking about how to make an API for this, the related issue can be found on the Envelop plugin repo, since it is not specific to Yoga: n1ru4l/envelop#1979 The main thing that I'm not sure about this approach is that it would create very strong bonds between resolvers of the schema, making the whole server rigid and error prone to add/remove resolvers. Imagine you already have a complete schema with careful fine grained cache control. If you now add a new root query, it means you will have to carefully think about every mutations or places in code that could possibly make this new resolver cached response stale, and update them. Same thing if you delete an existing root query. I would prefer a more global and approach, with as less configuration as possible. That would lead to a more predictable cache behaviour. |
I think one option would be if you can keep the core response cache simple and invert the responsibility to the userland. In our current implementation (apollo response cache) we are using the equivalent of In our case, we have flushCache mutations that can then flush all So the suggestion is to do as little as possible in the framework and invert to the user to define how to build keys and how to invalidate them, somehow. No idea how, just throwing some idea and see if someone can get a more refined idea :) |
That's a good idea, this is probably something you can actually do in a seperate custom plugin (which takes the same I like this approach because we are in a level of abstraction that begins to be too business dependent to provide a good default behaviour in the framework that would work for the majority of cases. Delegating this kind of advances use cases to end users (or even to more specialised sidecar plugins ?) is probably a good idea |
Is your feature request related to a problem? Please describe.
I'm trying to use Yoga Response Cache plugin in my API. However I'm facing an issue because I need to constantly invalidate most of the cache, rather than invalidating only what I'd like to.
The limiting factor is mostly when a mutation creates a new entity rather than modifies or deletes an entity. In such cases, I don't find a way to invalidate "related" operations cached that might be affected.
So far, I think this can be generalized to the following statement:
Description of a simplified use case
Let's consider a
User
type:and some queries that fetch those by range (e.g.
getUsersInRange
) or by prop (e.g.getUsersByRole
).Case1: a mutation creates an Entity
When a mutation create a new User, I can't invalidate the cached response for
getUsersByRange
orgetUsersByRole
in a granular fashion, I can only invalidate for the typenameUser
, leading to all cached responses having entities of typeUser
being invalidated.Case2: a mutation updates an Entity
if a mutation changes some Entity prop, leading to the need to invalidate the collection of Entities cached. E.g. a mutation changes
User { id: 1, role: 'admin' }
to{ id: 1, role: 'superuser'}
. The cache invalidation:getUsersByRole
with inputrole: 'admin'
because this cached response has collected the entityUser { id: 1 }
getUsersByRole
with inputrole: 'superuser'
because this cached response had not collected the entityUser { id: 1 }
.Describe the solution you'd like
I'd like to have better granular control over the invalidation, based on the query typename and the operation variables so that I can handle use Case 1 and 2.
Case 1:
E.g. I create a
User { id: 25, role: 'superuser' }
, I want to be able to invalidate:getUsersByRole
where inputrole
was'superuser'
(I know the same query with inputrole = 'admin'
orrole = 'user'
are not affected) andgetUsersInRange
where the id of the created user (newId
) is included in range[from, to]
of this operation input variables (I know cached responses forgetUsersInRange
with[from, to]
doesn't includenewId
can be maintained in the cache).Case 2:
E.g I update
User { id: 1, role: 'admin' }
to{ id: 1, role: 'superuser'}
, I want to be able to invalidate:getUsersByRole
where inputrole
was'superuser'
getUsersInRange
where input is[from=20, to=29]
(I know the other ranges are not affected)Describe alternatives you've considered
Use a dataloader for queries that returns collections of Entities based on some criteria. With a provided cache that I have control over, I can call the
invalidate
method for a precise key and/or loop over the cached items, parse the key and decide to invalidate or not.This workaround is not so great because all resolvers have to be executed, which can be very costly for collections of Entities. The Response Cache is more efficient as it completely bypass the resolvers once a response is cached.
Additional context
Reproduction scenario: https://codesandbox.io/p/devbox/shy-dream-vtlsz8
The text was updated successfully, but these errors were encountered: