GraphQL:实现常规列表的窗口分页

GraphQL:实现常规列表的窗口分页,graphql,graphql-js,Graphql,Graphql Js,我正在尝试使用“列表”实现窗口分页。我不需要带有连接的基于光标的解决方案,因为我需要向用户显示编号的页面 有“User”和“Post”对象,“User”与“Post”有一对多的关系 对模式使用graphql js, 以下是我的userType和postType模式: var userType = new GraphQLObjectType({ name: 'User', fields: () => ({ id: globalIdField('User'),

我正在尝试使用“列表”实现窗口分页。我不需要带有连接的基于光标的解决方案,因为我需要向用户显示编号的页面

有“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],
});
请注意“用户类型”中的“totalPosts”字段。由于用户将有其他列表,具有相同的分页需求,因此我将在片段中维护许多“total{Type}”变量。如果我能够以某种方式发送列表结果中的totalCount,则可以解决此问题

本期讨论如何在列表上实现包装器,以便在结果集中包含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],
});
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
posts
字段?我如何在这个包装器上使用“page”参数,就像我在原始用户类型中使用的那样

我应该如何将其连接到userType的posts字段?我如何在这个包装器上使用“page”参数,就像我在原始用户类型中使用的那样

一种简单的实现方法是定义一个哑包装器类型
postList
,如下所示:

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],
});
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
定义中,添加该包装类型的字段并定义其解析函数,如下所示。对于参数
页面
,只需在定义字段类型
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.
    },
},

谢谢成功了。不得不从postlistwrapper中删除接口:[nodeInterface],我很高兴您发现它很有用。根据您的反馈,我从
postList
wrapper中删除
interfaces
字段。谢谢