urql icon indicating copy to clipboard operation
urql copied to clipboard

RFC: Allow for selectively skipping local resolver with a hook option

Open mtourj opened this issue 2 years ago • 1 comments

Summary

Graphcache is great and the local resolvers feature works great for merging data together when doing cursor pagination. However, if I wanted to use the same query in multiple places and in some components I did NOT want to merge data when paginating, my hands are tied because if you apply a local resolver to a query, then it applies to ALL calls to that query. I tried setting requestPolicy to network-only but that does not seem to have an effect on whether local resolvers are used.

Proposed Solution

Perhaps a simple switch to skip the local resolver straight from the hooks. Maybe a skipLocalResolvers option or something similar?

Requirements

I am not familiar with the internals of urql, so really I'm just looking to have an option to decide whether a query will use the local resolvers I've written to resolve things or not, however that might best be implemented.

Thank you for the amazing work! Love using urql :)

mtourj avatar Aug 30 '22 17:08 mtourj

I don't know if this will also work for queries (as the docs only talk about mutations and I haven't tried it), but it may be possible to pass an "extra" argument to your query, and use this in the resolver to conditionally perform your merge?

https://formidable.com/open-source/urql/docs/graphcache/cache-updates/#variables-for-optimistic-updates

sarink avatar Sep 23 '22 22:09 sarink

This would be really useful, I'm having the same experience as you.

focux avatar Nov 25 '22 17:11 focux

Generally I would say this option already exists, let's say for a local resolver you are using the pagination but you want to opt out of it then you can do

const myResolver = relayPagination();

cacheExchange({
  resolvers: {
    Query: {
      list: (parent, args, cache, info) => {
        // or any other condition 😅 
        if (info.variables.skipPagination) {
          return cache.resolve('Query', 'list', args)
        }

        return myResolver(parent, args, cache, info);
      }
    }
  }
})

JoviDeCroock avatar Nov 25 '22 17:11 JoviDeCroock

Thanks @JoviDeCroock, that's very helpful.

mtourj avatar Nov 25 '22 17:11 mtourj

Generally I would say this option already exists, let's say for a local resolver you are using the pagination but you want to opt out of it then you can do

const myResolver = relayPagination();

cacheExchange({
  resolvers: {
    Query: {
      list: (parent, args, cache, info) => {
        // or any other condition 😅 
        if (info.variables.skipPagination) {
          return cache.resolve('Query', 'list', args)
        }

        return myResolver(parent, args, cache, info);
      }
    }
  }
})

Just tried this - info.variables seems to be getting filtered down before it is passed to cacheExchange resolvers. @JoviDeCroock , so I cannot do conditional behavior this way

mtourj avatar Nov 25 '22 18:11 mtourj

It shouldn't be based on the code here can look at it next week though which is used here

JoviDeCroock avatar Nov 25 '22 18:11 JoviDeCroock

Sounds good, much appreciated.

Yeah I'm not sure where it happens but it's definitely being passed in to useQuery and not making it into the info object.

For context I'm on Graphcache 4.4.3, although it seems that neither of the snippets you linked have changed since then, so might not be a relevant detail.

mtourj avatar Nov 25 '22 18:11 mtourj

Just tried in a sanbox, works great https://codesandbox.io/s/jovial-cloud-usm1t4?file=/src/components/Todos.js

JoviDeCroock avatar Nov 25 '22 19:11 JoviDeCroock

Okay I got it working, it turned out to be filtering it out because I had requestPolicy: "network-only" set, thank you :)

mtourj avatar Nov 25 '22 22:11 mtourj

Resolved by #3191 / #3306 which have been released in @urql/[email protected]

kitten avatar Jul 22 '23 01:07 kitten