我无法解析graphql嵌套类型。我可以成功获取UserMetrics
嵌套解析器,但父解析器对象(用户)为空。我误解了GraphQL解析器映射吗?
架构:
type User {
id: String!
metrics: UserMetrics
}
type UserMetrics {
lastLogin: String!
}
解析器:
Query: {
user(_, { id }, ctx) {
return { id };
}
},
User: {
metrics(): ({}), // UserMetrics.lastLogin doesn't fire without this
},
UserMetrics: {
lastLogin(user) {
console.log(user); // null
}
},
答案 0 :(得分:11)
这可能会让您感到有些困惑,不幸的是,文档并未提供嵌套类型如何工作的可靠示例。根据文档,解析器采用的第一个参数是:
包含从解析器返回的结果的对象 父母领域
因此,父(用户)解析某个字段(指标)。 如果此字段是标量,则不需要执行任何其他操作,这就是返回的内容。 否则将父分析的值传递给与“子”类型(UserMetrics)关联的解析器。然后,每个解析器都使用该值来解析它负责的字段。
在您提供的代码中,User
将metrics
解析为空对象(即{})。这是为UserMetrics中的任何字段传递给解析程序的值。严格地说,在这种情况下,在该值上运行console.log将返回{},而不是null。
试试这个:为metrics
字段注释掉你的解析器,而不是{ id }
,让你的查询返回{ id, metrics: { lastLogin: 'foo' }}
。运行它,您应该会看到一个控制台输出,显示传递给lastLogin
的解析程序的对象,在本例中为{ lastLogin: 'foo' }
。
一步一步,这里发生了什么:
user
字段正在解析为{id:'whateverIdYouProvided',metrics:{lastLogin:'foo'}}。由于它返回User
类型而不是标量,因此会将此值传递给User
内任何字段的解析器。id
这样的字段在这种情况下没有指定解析器,所以它使用默认解析器。这只是查看它收到的对象,如果找到与其字段名称匹配的属性,它将解析为该属性的值。如果它找不到该名称的任何属性,则返回null。在这种情况下,id是一个标量,所以它只是解析为'whateverIdYouProvided'而不需要再进一步。metrics
解析器,所以此字段也会使用默认解析器。在这种情况下,它解析为一个类型(UserMetrics),因此它查看给定的对象,找到一个名为metrics
的属性并将该值(即{ lastLogin: 'foo' }
)传递给任何内部字段的解析器UserMetrics。{ lastLogin: 'foo' }
- 可以使用。如果你没有在这里指定一个解析器,那么将再次使用默认的解析器,它将很乐意找到一个名为lastLogin的属性并解析它的值('foo')。如果您提供自定义解析器,就像您所做的那样,显然它将解析为您返回的任何内容(在代码的情况下为null)。如果根本没有调用lastLogin
解析程序,请确认您确实在查询中包含了该字段!查询中未包含的任何字段都不需要解析,因此不会调用它们的解析器。