wp-graphql / wp-graphql-smart-cache

Smart Caching & Cache Invalidation for WPGraphQL
60 stars 14 forks source link

Exclude specific queries/mutation from being served from the object cache #182

Open eplanne opened 1 year ago

eplanne commented 1 year ago

After turning on the object cache, the plugin does a great job at storing my query responses and serving them quicker form the cache. My issue is that I have certain queries and mutation that needs a unique call to the database even if the query/mutation string is identical.

One example: There is a countdown for each individual user based on certain actions they take on the site. The countdown is stored in the database together with their unique userId. I use a custom mutation with userId as variable to check the countdown in the database and return it back to the front end. In this case, the mutation doesn't change (it's still the same userId), but the result is cached so the user is served old data even if the countdown has changed. It's a React app + Apollo client.

Is there a setting to exclude certain queries / mutations from being served from the cache? I have managed to get around it by submitting a uuid as a variable for the respective queries and mutations for the time being, but it seems there might be a neater way to get around this.

jasonbahl commented 1 year ago

In this case, the mutation doesn't change (it's still the same userId), but the result is cached so the user is served old data even if the countdown has changed.

Can you get me more detail here? How is the data stored? How is it mutated? Events that change a user should purge caches with that user in the response.

Could you maybe provide some clear steps to reproduce so I could experience the same thing you're experiencing?

Is there a setting to exclude certain queries / mutations from being served from the cache?

Mutations shouldn't be getting cached at all. If they are, we definitely have a bug to investigate.

Can you confirm that mutations are indeed being cached for you? And if so, are you doing them over GET or POST request? Mutations should be done over POST requests and should bypass the Network Cache, and the object cache should not be in effect for mutations.

As far as excluding certain queries, I think we could use the "Persisted Queries" functionality to set specific queries to ignore the cache. 🤔

Will definitely look into this.

jasonbahl commented 1 year ago

@eplanne if you're doing per-user queries and mutations, how are you getting the user ID? Are they logged in and you're using the logged in user ID? And are you passing Authorization tokens and making Authenticated requests? Or are these all public requests?

revnelson commented 1 year ago

I'm having a related issue when querying for a guest's cart. Because they are not authenticated, the only identifier is the 'woocommerce-session' header, and with Object Cache enabled I am not able to get live updates. Being able to exclude specific queries would fix this issue.

jasonbahl commented 1 year ago

@revnelson @eplanne what do you envision the user / dev experience looking like for this?

How would one go about excluding a query from being cached?

Would it be something you would configure on the server? like provide a list of query IDs / operation names that should not be cached?

Or would you want to send something from the client indicating you would prefer an uncached response and, assuming the server respects that request you would get an uncached response?

Or maybe a bit of both?

jasonbahl commented 1 year ago

As far as mutations go, there's definitely a bug causing mutations to be cached.

related #196 #234

eplanne commented 1 year ago

@jasonbahl Apologies for the very late response. Great that it's solved for mutations.

To respond your first questions regarding how the queries were called - they were all public requests. Regarding the second question about the dev experience - I think the most useful and simple feature would be to be able to send something from the client which would ensure that the server response is ignoring the cache and sending fresh data. To be able to configure it on the server would also be useful, but I would say that's secondary to using a key or trigger from client side.

Is there any workaround or suggestion you would have for achieving this for a public query with the plugin enabled?

webc-charles commented 5 months ago

hello, is there any update for this?

JaidonLalor commented 2 months ago

Work around: add a variable like time or a random number to the query every time it's called. This way is always technically a new query.

// Trigger refetchCartData with a timestamp to avoid caching
    const fetchLatestCart = useCallback(() => {
      const queryId = Math.random().toString(36).substring(7);
      refetchCartData({ variables: { queryId } });
    }, [refetchCartData]);