Search code examples
node.jspaginationgraphqlsequelize.jsapollo

How to implement pagination in graphql which returns pagination metadata along with dataset


Currently i use graphql default pagination, that is by using limit offset (code given below) . which is working fine. but instead of the team list how can we include pagination metadata. and return the pagination metadata along with this. I use sequalize to fetch the data

            type Query {
            allTeams(page:Int, pageSize:Int): [Team]
        }
        type Team {
            id: Int
            name: String  
        }

        //resolver with pagination   

        const paginate = ( page, pageSize ) => { 
          var offset = page * pageSize;
          var limit =  pageSize;  
          return {
            offset,
            limit,
          };
        };

        export const resolvers = {
            Query: {     
                  allTeams: async (obj, args, context, info ) =>  Teams.findAll(           
                  paginate( args.page, args.pageSize ),         
                ),
            },
        }

The above code will only return the list of teams . Is there any way i can return a the output as which contains team list and pagination details

         {
          "data": {
            "allTeams": [
              {
                "id": 4,
                "name": "Team created from postman",

              },
              {
                "id": 5,
                "name": "Team created from postman",

              }
              ]
            },
               "pageInfo": {
                "currentPage": 2,
                "perPage": 2,
                "itemCount": 4,
                "pageCount": 2,
                "hasPreviousPage": true,
                "hasNextPage": false
              }
        }

Solution

  • Yep, you'll just need to add the pagination metadata to your schema and provide the data in your resolvers. So for the output you're looking to achieve, the schema would look like:

    type Query {
      teams(page:Int, pageSize:Int): TeamsConnection
    }
    
    type TeamsConnection {
      results: [Team]
      pageInfo: PageInfo
    }
    
    type Team {
      id: Int
      name: String  
    }
    
    type PageInfo {
      currentPage: Int
      perPage: Int
      itemCount: Int
      pageCount: Int
      hasPreviousPage: Boolean
      hasNextPage: Boolean
    }
    
    

    Your resolver would then need to return the new shape of the response data. So something like:

    export const resolvers = {
      Query: {     
        allTeams: async (obj, args, context, info ) => {
          const results = await Teams.findAll(           
            paginate(args.page, args.pageSize),         
          );
          return {
            results,
            pageInfo: {...}
          }
        }
      }
    }