【问题标题】:GraphQL : Implementing windowed pagination for regular listGraphQL:为常规列表实现窗口分页
【发布时间】:2016-12-20 04:41:57
【问题描述】:

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

有“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}”变量。如果我能以某种方式在 List 结果中发送 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],
});

但是我应该如何将它连接到userTypeposts 字段?以及如何在此包装器上使用“页面”参数,就像我在原始 userType 中使用的那样?

【问题讨论】:

    标签: graphql graphql-js


    【解决方案1】:

    我应该如何将它连接到 userType 的帖子字段?以及如何在此包装器上使用“页面”参数,就像我在原始 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.
        },
    },
    

    【讨论】:

    • 谢谢!有效。必须从 postList 包装器中删除接口:[nodeInterface]
    • 很高兴您发现它很有用。根据您的反馈,我从 postList 包装器中删除了 interfaces 字段。谢谢!
    猜你喜欢
    • 2017-11-18
    • 2018-07-26
    • 2021-06-05
    • 2018-10-18
    • 1970-01-01
    • 1970-01-01
    • 2011-04-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多