在vanilla GraphQL

时间:2018-02-15 22:23:18

标签: mongodb mongoose graphql ecmascript-5 graphql-js

到目前为止,我发现的每个教程都通过Apollo,Relay或其他一些魔术框架在GraphQL中实现了分页。我希望能在这里找到类似问题的答案,但它们并不存在。我了解如何设置查询,但我不清楚如何实施解析器。

有人能指出我正确的方向吗?我正在使用mongoose / MongoDB和ES5,如果有帮助的话。

编辑:值得注意的是,如果您选择使用graphql.jslearning GraphQL的官方网站没有分页条目。

编辑2:我喜欢一些人在进行研究之前投票关闭问题,而其他人则利用他们的知识帮助他人。无论你怎么努力,你都无法阻止进步。 (:

2 个答案:

答案 0 :(得分:5)

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
});

并在查询时:

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

创建了一个启动板here

答案 1 :(得分:3)

您可以通过多种方式实现分页,但这里有两个简单的示例解析器,它们使用Mongoose来帮助您入门:

使用限制和跳过的简单分页

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

使用_id作为光标

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