如何在GraphQL中解析嵌套类型?

时间:2017-07-13 14:33:22

标签: javascript graphql

我无法解析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
    }
},

1 个答案:

答案 0 :(得分:11)

这可能会让您感到有些困惑,不幸的是,文档并未提供嵌套类型如何工作的可靠示例。根据文档,解析器采用的第一个参数是:

  

包含从解析器返回的结果的对象   父母领域

因此,父(用户)解析某个字段(指标)。 如果此字段是标量,则不需要执行任何其他操作,这就是返回的内容。 否则将父分析的值传递给与“子”类型(UserMetrics)关联的解析器。然后,每个解析器都使用该值来解析它负责的字段。

在您提供的代码中,Usermetrics解析为空对象(即{})。这是为UserMetrics中的任何字段传递给解析程序的值。严格地说,在这种情况下,在该值上运行console.log将返回{},而不是null。

试试这个:为metrics字段注释掉你的解析器,而不是{ id },让你的查询返回{ id, metrics: { lastLogin: 'foo' }}。运行它,您应该会看到一个控制台输出,显示传递给lastLogin的解析程序的对象,在本例中为{ lastLogin: 'foo' }

一步一步,这里发生了什么:

  1. 查询的user字段正在解析为{id:'whateverIdYouProvided',metrics:{lastLogin:'foo'}}。由于它返回User类型而不是标量,因此会将此值传递给User内任何字段的解析器。
  2. id这样的字段在这种情况下没有指定解析器,所以它使用默认解析器。这只是查看它收到的对象,如果找到与其字段名称匹配的属性,它将解析为该属性的值。如果它找不到该名称的任何属性,则返回null。在这种情况下,id是一个标量,所以它只是解析为'whateverIdYouProvided'而不需要再进一步。
  3. 因为我们注释掉了metrics解析器,所以此字段也会使用默认解析器。在这种情况下,它解析为一个类型(UserMetrics),因此它查看给定的对象,找到一个名为metrics的属性并将该值(即{ lastLogin: 'foo' })传递给任何内部字段的解析器UserMetrics。
  4. UserMetrics有一个名为lastLogin的字段。它的解析器收到上述值 - { lastLogin: 'foo' } - 可以使用。如果你没有在这里指定一个解析器,那么将再次使用默认的解析器,它将很乐意找到一个名为lastLogin的属性并解析它的值('foo')。如果您提供自定义解析器,就像您所做的那样,显然它将解析为您返回的任何内容(在代码的情况下为null)。
  5. 如果根本没有调用lastLogin解析程序,请确认您确实在查询中包含了该字段!查询中未包含的任何字段都不需要解析,因此不会调用它们的解析器。