mickhansen / graphql-sequelize

GraphQL & Relay for MySQL & Postgres via Sequelize
MIT License
1.9k stars 172 forks source link

Problem integrating connection types and dataloader for paginated (cursor) queries #695

Closed dziraf closed 3 years ago

dziraf commented 4 years ago

Hi, I'm using the latest version of this library with dataloader-sequelize@2.1.2.

After upgrading dataloader-sequelize to v>=2.0 the batching basically stopped working until I readjusted my field resolvers to follow the example in this PR: https://github.com/mickhansen/graphql-sequelize/pull/671

This has solved the issue for fields which have model/association resolvers, i. e.:

resolve: (...args) => resolver(User.Roles, { separate: false })(...args)

The above example works. However, I have issues getting it work with connections. Here is a connection I have created:

const PostConnection = createConnection({
  name: 'PostConnection',
  nodeType: PostType,
  target: Channel.Posts,
  connectionFields: {
    total: {
      type: GraphQLInt,
      resolve: ({ source }) => source.countPosts()
    }
  },
  edgeFields: {}
});

And here is the postsConnection resolver for Channel type:

        postsConnection: {
          type: PostConnection.connectionType,
          args: PostConnection.connectionArgs,
          resolve: (...args) => PostConnection.resolve(...args)
        },

This does go through the Dataloader - I can see that posts are being fetched. The query also works properly the first time it is run, when the cursor (after in connection args) argument equals to empty string:

query Channels {
  channels {
    id
    postsConnection(first: 10, after: "") {
      edges {
        node {
          id
          name
        }
      }
    }
  }
}

The problem appears when after argument is not empty:

query Channels {
  channels {
    id
    postsConnection(first: 10, after: "WyIwNTU0YTZjMS01MDRmLTQ3N2ItODM2My1lYzI4YjVhOTAxZmYiLDld") {
      edges {
        node {
          id
          name
        }
      }
    }
  }
}

When I want to load 10 more results, a database error is thrown: SequelizeDatabaseError: argument of LIMIT must be type bigint, not type integer[]

And it is related to this part of the generated query:

(...)
ORDER BY "subquery_order_0" DESC LIMIT ARRAY[10,10] OFFSET 10) AS sub) AS "Post" ORDER BY "subquery_order_0" DESC;

When I change back postsConnection resolver to:

resolve: PostConnection.resolve

the pagination works, but dataloader doesn't. I end up with an extremely slow execution time.

Note: Channel and Post have many-to-many relation.

At first I thought it was due to dataloader-sequelize being updated to v2 but after I'd downgraded it to v1.7 (and reverted my changes to field resolvers) I end up with a working dataloader but broken pagination for Connections, so the end result is the same.

I found a closed issue with similar problem: https://github.com/mickhansen/graphql-sequelize/issues/673 but the cause seems to be different because I don't use Connection for channels?

stale[bot] commented 3 years ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.