apollographql / apollo-client

:rocket:  A fully-featured, production ready caching GraphQL client for every UI framework and GraphQL server.
https://apollographql.com/client
MIT License
19.34k stars 2.65k forks source link

Passing query variables to Apollo @connection directive key #11099

Open malininss opened 1 year ago

malininss commented 1 year ago

I'm trying to use the @connection directive in my graphql query: https://www.apollographql.com/docs/react/pagination/key-args/#the-connection-directive

But I need to pass the key from the query variable. Everything is as in the documentation above:

const FEED_QUERY = gql`
  query Feed($offset: Int, $limit: Int, $feedKey: String) {
    feed(offset: $offset, limit: $limit) @connection(key: $feedKey) {
      edges {
        node { ... }
      }
      pageInfo {
        endCursor
        hasNextPage
      }
    }
  }
`;

However, when I make a request in this way, I get the response:

Variable "$feedKey" is never used in operation "Feed".

Therefore, for this functionality to work, I need to accept this variable $feedKeyon the server and do nothing with it. But this negates the whole idea of using @connection and a variable as a key. After all, if I start accepting $feedKey on the server and do nothing with this variable, I can specify it in keyArgs in the typePolicies property in the same way.

Depending on the location on the site where the request is called, I need to pass different keys to @connectionso that different keys are saved in the cache.

It seems that if this functionality does not work as described in the documentation, it is not relevant? Or am I missing something.

What is the best way for me to proceed in this case? Please help me figure it out.

phryneas commented 1 year ago

The @connection directive should be removed by the QueryManager before passing the query to the Link, and if you are using HttpLink, that should per default remove unused variables.
Are you maybe using the includeUnusedVariables option of HttpLink?

malininss commented 1 year ago

No, I don't have the includeUnusedVariables option of HttpLink set. The variable $feedKey (in this example) is removed from body.variables, But it's not removed from the query.

So, the request will be sent with a payload like this:

{
  operationName: 'Feed',
  query: 'query Feed($offset: Int, $limit: Int, $feedKey: String)...',
  variables: { offset: 0, limit: 10 },
}

As you can see, it remains in the query itself. It seems that this is what causes the server error when an unused variable remains in the query itself.

I found the following code: https://github.com/apollographql/apollo-client/blob/main/src/link/http/createHttpLink.ts#L99 I see here that we're just removing the variables from body.variables, but not from the query.

Moreover, the comment states:

A variable type definition at the top level of a query is not enough to silence server-side errors about the variable being unused...

I may not fully understand the meaning of this comment, but it seems that any declared variable at the top level, as in the example $feedKey, if it is not actually used somewhere in the request, will cause a server error

caylahamann commented 1 year ago

I'd love to take a closer look at this!

jerelmiller commented 1 year ago

Hey @malininss 👋

You're right, we should be removing that variable definition from the query itself when stripping that @connection directive.

As a temporary workaround, are you able to hardcode the key you want to use in the query itself? This should at least silence the server errors.

query Feed($offset: Int, $limit: Int) {
  feed(offset: $offset, limit: $limit) @connection(key: "YourFeedKey") {
    edges {
      node { ... }
    }
    pageInfo {
      endCursor
      hasNextPage
    }
  }
}