Last active
November 9, 2023 10:29
-
-
Save du5rte/92a49f9aa8705ba59da3710fbbfe4741 to your computer and use it in GitHub Desktop.
GraphQL UserConnection with totalCount
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import { GraphQLInt, GraphQLNonNull, GraphQLInputObjectType } from "graphql"; | |
| import { connectionDefinitions, connectionArgs } from "graphql-relay"; | |
| import UserType from "./UserType"; | |
| // References | |
| // http://graphql.org/learn/pagination/ | |
| // http://dev.apollodata.com/react/pagination.html | |
| // https://www.reindex.io/blog/relay-graphql-pagination-with-mongodb/ | |
| // https://github.com/graphql/graphql-relay-js | |
| // https://dev-blog.apollodata.com/understanding-pagination-rest-graphql-and-relay-b10f835549e7 | |
| // totalCount | |
| // neither graphql-relay-js or relay-mongodb-connection expose totalCount | |
| // https://github.com/mikberg/relay-mongodb-connection | |
| // adriexnet has submitted a pull request to graphql-relay-js but the library seems a little dead | |
| // https://github.com/adriexnet/relay-mongodb-connection/blob/develop/src/connectionFromMongoCursor.js | |
| // graphql-relay-js can be manually overwritten throught the connectionFields | |
| // https://stackoverflow.com/questions/34192507/how-to-pass-total-count-to-the-client-in-pageinfo | |
| // pageInfo | |
| // pageInfo.hasPreviousPage is always false if you are paging forwards | |
| // https://github.com/graphql/graphql-relay-js/issues/58 | |
| // https://github.com/graphql/graphql-relay-js/issues/103 | |
| // relay-mongodb-connection uses it's own logic which can be modified here | |
| // https://github.com/adriexnet/relay-mongodb-connection/blob/develop/src/utils.js#L39 | |
| export const { | |
| connectionType, | |
| edgeType | |
| } = connectionDefinitions({ | |
| nodeType: UserType, | |
| connectionFields: () => ({ | |
| totalCount: { | |
| type: new GraphQLNonNull(GraphQLInt), | |
| resolve: connection => connection.totalCount, | |
| // description: `A count of the total number of objects in this connection, ignoring pagination. | |
| // This allows a client to fetch the first five objects by passing "5" as the | |
| // argument to "first", then fetch the total count so it could display "5 of 83", | |
| // for example.` | |
| } | |
| }) | |
| }); | |
| const Pagination = new GraphQLInputObjectType({ | |
| name: 'Pagination', | |
| fields: connectionArgs | |
| }); | |
| export const UserConnection = connectionType; | |
| export const UserEdge = edgeType; | |
| export const UserPagination = Pagination; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import { GraphQLString } from "graphql"; | |
| import { connectionArgs } from "graphql-relay"; | |
| import connectionFromMongoCursor from "relay-mongodb-connection"; | |
| import infoToProjection from "graphql-mongodb-projection"; | |
| import { User } from "../../models"; | |
| import { UserConnection, UserPagination } from "./UserConnection"; | |
| export const users = { | |
| type: UserConnection, | |
| args: { | |
| category: { type: GraphQLString }, | |
| pagination: { type: UserPagination } | |
| }, | |
| async resolve(root, { category, pagination }, ctx, info) { | |
| const { user } = ctx.state; | |
| const hasCategory = category ? { category } : {}; | |
| const query = { ...hasCategory }; | |
| const projection = infoToProjection(info); | |
| try { | |
| const usersList = await connectionFromMongoCursor( | |
| User.secureFind(user, query, projection), | |
| pagination | |
| ); | |
| if (!usersList) throw "not found"; | |
| const totalCount = await User.secureCount(user, query); | |
| const userListWithTotalCount = { | |
| ...usersList, | |
| totalCount | |
| }; | |
| return userListWithTotalCount; | |
| } catch (error) { | |
| throw error; | |
| } | |
| } | |
| }; | |
| export default users; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| query { | |
| users(pagination: {first: 3}) { | |
| totalCount | |
| edges { | |
| node { | |
| _id | |
| } | |
| } | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| { | |
| "data": { | |
| "users": { | |
| "totalCount": 25, | |
| "edges": [ | |
| { | |
| "node": { | |
| "_id": "58eba048307ce2316004bb2c" | |
| } | |
| }, | |
| { | |
| "node": { | |
| "_id": "5922c481ade5f823f48d69af" | |
| } | |
| }, | |
| { | |
| "node": { | |
| "_id": "5928372952ae8416ec532ef9" | |
| } | |
| } | |
| ] | |
| } | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment