【问题标题】:graphql throws unknown argument errorgraphql 抛出未知参数错误
【发布时间】:2017-07-13 00:31:17
【问题描述】:

似乎我没有得到有关 graphql 的基本知识。

我试图通过它的 id 来获取用户,而这又是另一个查询的结果。在这种情况下,查询一些会话数据。

我不明白为什么会发生错误。

这是我的代码:

{
    session(key: "558fd6c627267d737d11e758f1ae48cae71fc9b584e2882926ad5470c88d7c3ace08c9c7") {
        userId
        expires
        user(id: userId) {
            name
        }
    }
}

我得到了

“会话”类型的字段“用户”上的未知参数“id”

我的架构如下所示:

type Session {
    userId: String,
    expires: String,
    user: User
}

type User {
    _id: String
    name: String
    email: String
    firstName: String
    lastName: String
}

type Query {
    session(key: String!): Session
    user(id: String!): User
}

2017 年 2 月 23 日附录

很抱歉,我在最初的帖子中没有足够明确地说明相应的解析器。是的,我的解析器已定义并且 e. G。如果我不添加用户,该查询适用于会话。

这是我的根:

{
    Query: {
        async user(parentValue, args, req) {
            let user = await adapters.users.byId(args.id);
            return user;
        },
        async session(parentValue, args, req) {
            let session = await adapters.session(args.key);
            let userId = session.session.userId;
            let expires = session.expires;
            return {userId: userId, expires: expires};
        }
    }

}

【问题讨论】:

    标签: graphql


    【解决方案1】:

    您需要在Session 类型的字段user 上创建一些resolver 函数,因为GraphQL 不知道如何返回user。在graphql-js 中看起来像这样

    const Session = new GraphQLObjectType({
        name: 'Session',
        fields: {
            userId: { type: GraphQLString },
            expires: { type: GraphQLString },
            user: {
                type: User, // it is your GraphQL type
                resolve: function(obj, args, context){
                    // obj is the session object returned by ID specified in the query
                    // it contains attributes userId and expires
                    // however graphql does not know you want to use the userId in order to retrieve user of this session
                    // that is why you need to specify the value for field user in type Session
                    return db.User.findById(obj.userId).then(function(user){
                        return user;
                    });
                }
            }
        }
    });
    

    这只是一个来自 Node.js 的简单示例,向您展示如何返回 user 实例。您可以指定如何检索每个 GraphQL 类型中每个字段的值(每个字段都可以有自己的 resolve 函数)。

    我建议您阅读有关 root and resolvers 的 GraphQL 文档

    编辑

    我将向您展示如何处理这种情况的示例。让我们考虑两种类型:UserSession

    type User {
        _id: String
        name: String
    }
    
    type Session {
        expires: String
        user: User
    }
    

    如果您希望查询返回Session 对象及其User,则无需在Session 类型中包含userId 字段。 您可以通过两种方式解决这种情况。第一个是对session 查询使用单个解析器。

    {
        Query: {
            async session(parentValue, args, req) {
                let session = await adapters.session(args.key);
                // now you have your session object with expires and userId attributes
                // in order to return session with user from query, you can simply retrieve user with userId
                let user = await adapter.users.byId(session.userId);
                return { expires: session.expires, user: user }
            }
        }
    }
    

    这是您的第一个选择。使用该解决方案,您可以通过单个查询返回 session 分配给它的 user 对象,并且在 Session 类型的任何字段上没有额外的 resolve 方法。第二种解决方案是我之前展示过的解决方案,您在 Session 类型的字段 user 上使用 resolve 方法 - 所以您只需告诉 GraphQL 它应该如何获取该字段的值。

    【讨论】:

    • 好吧,我的错,我认为不用说每个查询都有解析器。如果我没有解析器,程序甚至会在此错误消息之前崩溃。但为了完整和明确起见,我会将我的解析器添加到上面的代码中。如果我只是在没有用户的情况下查询会话,则该查询有效。另一件事:我使用 Apollo 的 graphql-tools 进行模式定义,所以它的定义是基于 GraphQL 类型语言的。查看 2017 年 2 月 23 日的附录
    • 我编辑了答案,为您的案例提供了一个示例
    猜你喜欢
    • 2019-09-16
    • 1970-01-01
    • 2018-12-03
    • 2019-11-02
    • 2018-03-18
    • 2013-04-15
    • 1970-01-01
    • 1970-01-01
    • 2017-09-06
    相关资源
    最近更新 更多