GraphQL:传递给执行的 rootValue 规范是什么?

Ali*_*iba 3 graphql

我使用 express-graphql 初始化rootValue并将其传递给 GraphQL 的执行函数。我想知道什么是rootValue规范。我看过一些简单的例子,但我对完整的规范很感兴趣。

Dan*_*den 6

rootValue是特定于 javascript 实现的,据我所知,不是官方规范明确要求的。

这是文档中resolve提供的函数(或解析器)的类型定义:

type GraphQLFieldResolveFn = (
  source?: any,
  args?: {[argName: string]: any},
  context?: any,
  info?: GraphQLResolveInfo
) => any
Run Code Online (Sandbox Code Playgroud)

传递给解析器的第一个参数是“源”、“根”或“父”值。字段总是与某种对象类型相关联。“源”值只是返回该对象类型的字段解析为的值。例如,给定如下查询:

{
  user(id: 1) {
    location {
      city
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

user字段返回对象类型。当它解析时,解析的值location作为“源”传递给解析器。类似地,当location解析时,解析的值将传递给所有请求字段的解析器,例如city.

在我们的示例中,useris 字段,就像任何其他字段一样,它恰好在Query类型上,但该类型本身仍然是一个 Object 类型。因为它是一个字段,所以通过调用与之关联的解析器来解析它。但是因为它位于查询的根部,所以没有“源”值。这是rootValue您传递给的唯一目的execute——它作为“源”值传递给每个根级别解析器。

换句话说,无论您设置什么,都rootValue将作为第一个参数传递给Query,MutationSubscription类型的每个字段的解析器。

由于rootValue仅可用于根级别解析器,因此它的使用非常有限。所有解析器都应该可用的任何数据应该包含在上下文中。

为了完成起见,我应该注意到有一些示例展示了如何使用 SDL 和buildSchema. 因为buildSchema不提供为任何字段提供解析器的方法,这些示例提供了一种通过rootValue. 这是有效的,因为,正如文档所述:

[如果] 未提供解析器函数,则使用默认解析器,该解析器在与字段同名的源上查找方法。如果找到,则使用 (args, context, info) 调用该方法。

但是,同样,rootValue仅适用于根类型(查询、变异和订阅)上的字段。如果您以这种方式创建架构,您将无法为任何其他类型的字段定义解析器。换句话说,不要这样做。有关更多详细信息,请参阅此答案