Implementing pagination in vanilla GraphQL

Each tutorial that I have found so far has reached pagination in GraphQL through Apollo, Relay, or some other magic framework. I was hoping to find answers to such questions, but they do not exist. I understand how to configure queries, but I do not understand how I will implement the solutions.

Can someone point me in the right direction? I use mongoose / MongoDB and ES5 if this helps.

EDIT: It is worth noting that the official website of GraphQL training does not have a pagination entry if you decide to use it graphql.js.

EDIT 2: I like that there are some people who vote to close questions before doing their research, while others use their knowledge to help others. You cannot stop progress, no matter how hard you try. (

+4
source share
2 answers

Pagination Page vanilla GraphQL

// Pagination argument type to represent offset and limit arguments
const PaginationArgType = new GraphQLInputObjectType({
  name: 'PaginationArg',
  fields: {
    offset: {
      type: GraphQLInt,
      description: "Skip n rows."
    },
    first: {
      type: GraphQLInt,
      description: "First n rows after the offset."
    },
  }
})

// Function to generate paginated list type for a GraphQLObjectType (for representing paginated response)
// Accepts a GraphQLObjectType as an argument and gives a paginated list type to represent paginated response.
const PaginatedListType = (ItemType) => new GraphQLObjectType({
  name: 'Paginated' + ItemType, // So that a new type name is generated for each item type, when we want paginated types for different types (eg. for Person, Book, etc.). Otherwise, GraphQL would complain saying that duplicate type is created when there are multiple paginated types.
  fields: {
    count: { type: GraphQLInt },
    items: { type: new GraphQLList(ItemType) }
  }
})

// Type for representing a single item. eg. Person
const PersonType = new GraphQLObjectType({
  name: 'Person',
  fields: {
    id: { type: new GraphQLNonNull(GraphQLID) },
    name: { type: GraphQLString },
  }
})

// Query type which accepts pagination arguments with resolve function
const PersonQueryTypes = {
  people: {
    type: PaginatedListType(PersonType),
    args: { 
      pagination: { 
        type: PaginationArgType, 
        defaultValue: { offset: 0, first: 10 } 
      },
    },
    resolve: (_, args) => {
      const { offset, first } = args.pagination
      // Call MongoDB/Mongoose functions to fetch data and count from database here.
      return {
        items: People.find().skip(offset).limit(first).exec()
        count: People.count()
      }
    },
  }
}

// Root query type
const QueryType = new GraphQLObjectType({
  name: 'QueryType',
  fields: {
    ...PersonQueryTypes,
  },
});

// GraphQL Schema
const Schema = new GraphQLSchema({
  query: QueryType
});

and upon request:

{
  people(pagination: {offset: 0, first: 10}) {
    items {
      id
      name
    }
    count
  }
}

Have created a launchpad here .

+3
source

There are several ways to implement pagination, but here are two simple examples that Mongoose uses to run:

Simple pagination using restriction and skip :

(obj, { pageSize = 10, page = 0 }) => {
  return Foo.find()
    .skip(page*pageSize)
    .limit(pageSize)
    .exec()
}

Using _id as a cursor :

(obj, { pageSize = 10, cursor }) => {
  const params = cursor ? {'_id': {'$gt': cursor}} : undefined
  return Foo.find(params).limit(pageSize).exec()
}
+2

Source: https://habr.com/ru/post/1693715/


All Articles