GraphQL:为常规列表实现窗口分页
GraphQL : Implementing windowed pagination for regular list
我正在尝试使用 "List" 实现窗口分页。我不需要带有连接的基于游标的解决方案,因为我需要向用户显示编号的页面。
有 "User" 和 "Post" 个对象。"User" 与 "Post" 具有一对多关系。
使用 graphql-js 作为模式,
这是我的 userType 和 postType 模式:
var userType = new GraphQLObjectType({
name: 'User',
fields: () => ({
id: globalIdField('User'),
posts: {
type: new GraphQLList(postType),
args: {
page:{
type: GraphQLInt,
defaultValue: 0
}
},
resolve: (_, args) => {
//code to return relevant result set
},
},
totalPosts:{
type: GraphQLInt,
resolve: () => {
//code to return total count
}
},
}),
interfaces: [nodeInterface],
});
var postType = new GraphQLObjectType({
name: 'Post',
fields: () => ({
id: globalIdField('Post'),
name: {type: GraphQLString},
//other fields
}),
interfaces: [nodeInterface],
});
请注意 "userType" 中的 "totalPosts" 字段。由于将为用户提供其他列表,具有相同的分页需求,我将最终在片段中维护很多 "total{Type}" 变量。如果我能以某种方式在列表结果中发送 totalCount,这就可以解决。
https://github.com/facebook/graphql/issues/4这个问题讨论了在 List 上实现一个包装器以将 totalCount 包含在结果集中。
我试过像这样创建一个包装器:
var postList = new GraphQLObjectType({
name: 'PostList',
fields:()=>({
count: {
type: GraphQLInt,
resolve: ()=>getPosts().length //this is total count
},
edges: {
type: new GraphQLList(postType),
resolve: () => {
return getPosts() ; // this is results for the page, though I don't know how to use 'page' argument here
},
}
}),
interfaces: [nodeInterface],
});
但是我应该如何将其连接到 userType
的 posts
字段?我如何在这个包装器上使用 'page' 参数,就像我在原始 userType 中使用的那样?
how should I connect this to the userType's posts field? And how can I use a 'page' argument on this wrapper, like I have in original userType?
一个简单的方法来实现你想要做的事情是定义一个 dumb 包装器类型 postList
像这样:
var postList = new GraphQLObjectType({
name: 'PostList',
fields:()=>({
count: { type: GraphQLInt },
edges: { type: new GraphQLList(postType) }
// Consider renaming 'edges'. In your case, it's a list, not a
// connection. So, it can cause confusion in the long run.
}),
});
然后在 userType
定义中,添加该包装器类型的字段并定义其解析函数,如下所示。至于参数page
,在定义字段类型posts
.
时描述即可
posts: {
type: postList,
args: {
page:{
type: GraphQLInt,
defaultValue: 0
},
...otherArgs
},
resolve: async (_, {page, ...otherArgs}) => {
// Get posts for the given page number.
const posts = await db.getPosts(page);
// Prepare a server-side object, which corresponds to GraphQL
// object type postList.
const postListObj = {
count: posts.length,
edges: posts
};
// Consider renaming 'edges'. In your case, it's a list, not a
// connection. So, it can cause confusion in the long run.
},
},
我正在尝试使用 "List" 实现窗口分页。我不需要带有连接的基于游标的解决方案,因为我需要向用户显示编号的页面。
有 "User" 和 "Post" 个对象。"User" 与 "Post" 具有一对多关系。
使用 graphql-js 作为模式, 这是我的 userType 和 postType 模式:
var userType = new GraphQLObjectType({
name: 'User',
fields: () => ({
id: globalIdField('User'),
posts: {
type: new GraphQLList(postType),
args: {
page:{
type: GraphQLInt,
defaultValue: 0
}
},
resolve: (_, args) => {
//code to return relevant result set
},
},
totalPosts:{
type: GraphQLInt,
resolve: () => {
//code to return total count
}
},
}),
interfaces: [nodeInterface],
});
var postType = new GraphQLObjectType({
name: 'Post',
fields: () => ({
id: globalIdField('Post'),
name: {type: GraphQLString},
//other fields
}),
interfaces: [nodeInterface],
});
请注意 "userType" 中的 "totalPosts" 字段。由于将为用户提供其他列表,具有相同的分页需求,我将最终在片段中维护很多 "total{Type}" 变量。如果我能以某种方式在列表结果中发送 totalCount,这就可以解决。
https://github.com/facebook/graphql/issues/4这个问题讨论了在 List 上实现一个包装器以将 totalCount 包含在结果集中。
我试过像这样创建一个包装器:
var postList = new GraphQLObjectType({
name: 'PostList',
fields:()=>({
count: {
type: GraphQLInt,
resolve: ()=>getPosts().length //this is total count
},
edges: {
type: new GraphQLList(postType),
resolve: () => {
return getPosts() ; // this is results for the page, though I don't know how to use 'page' argument here
},
}
}),
interfaces: [nodeInterface],
});
但是我应该如何将其连接到 userType
的 posts
字段?我如何在这个包装器上使用 'page' 参数,就像我在原始 userType 中使用的那样?
how should I connect this to the userType's posts field? And how can I use a 'page' argument on this wrapper, like I have in original userType?
一个简单的方法来实现你想要做的事情是定义一个 dumb 包装器类型 postList
像这样:
var postList = new GraphQLObjectType({
name: 'PostList',
fields:()=>({
count: { type: GraphQLInt },
edges: { type: new GraphQLList(postType) }
// Consider renaming 'edges'. In your case, it's a list, not a
// connection. So, it can cause confusion in the long run.
}),
});
然后在 userType
定义中,添加该包装器类型的字段并定义其解析函数,如下所示。至于参数page
,在定义字段类型posts
.
posts: {
type: postList,
args: {
page:{
type: GraphQLInt,
defaultValue: 0
},
...otherArgs
},
resolve: async (_, {page, ...otherArgs}) => {
// Get posts for the given page number.
const posts = await db.getPosts(page);
// Prepare a server-side object, which corresponds to GraphQL
// object type postList.
const postListObj = {
count: posts.length,
edges: posts
};
// Consider renaming 'edges'. In your case, it's a list, not a
// connection. So, it can cause confusion in the long run.
},
},