GraphQL 解析器参数(根、参数、上下文)的错误顺序
Posted
技术标签:
【中文标题】GraphQL 解析器参数(根、参数、上下文)的错误顺序【英文标题】:Wrong order of GraphQL resolver arguments (root, args, context) 【发布时间】:2018-07-15 17:58:45 【问题描述】:我想知道为什么我的论点似乎在我的 GraphQL 解析器中切换了。我正在使用 express-graphql。
一个解析器的示例:
getLocalDrivers: async (parent, args, ctx) =>
console.log(ctx);
我已经编写了文档中出现的参数名称:http://graphql.org/learn/execution/
但是当我调试和检查对象时,似乎 args 对象是第一个,上下文是第二个,父/根是第三个。
父母:
Object location: "020202"
参数:
IncomingMessage _readableState: ReadableState, readable: false, domain: null, …
上下文:
Object fieldName: "getLocalDrivers", fieldNodes: ....
一些服务器代码:
app.use(
"/graphql",
graphqlHTTP(
schema,
graphiql: true,
rootValue: rootResolver
)
);
我的根解析器:
var rootResolver =
getLocalDrivers: async (obj, args, ctx) =>
console.log(ctx);
架构:
var buildSchema = require("graphql");
var schema = buildSchema(`
type Query
getLocalDrivers(location: String): [Driver]
type Driver
name: String
location: String
`);
【问题讨论】:
【参考方案1】:如果为某个字段定义了resolve
函数,那么当 GraphQL 解析该字段时,它将向该函数传递 四个 参数:
-
父字段解析为的值(通常称为
obj
或root
)
该字段的参数
上下文
描述整个 GraphQL 请求的信息对象
如果特定字段没有解析函数,GraphQL 将使用默认解析器,该解析器仅搜索父字段上的属性并在找到时使用该属性。
所以您的getLocalDrivers
查询可以返回Driver
对象的数组,并且只要Driver
对象具有name
属性,name
字段 将解析为该属性的值。
巧合的是,Driver
对象上的 name
属性也可以是一个函数。在这种情况下,GraphQL 会调用该函数来获取它的返回值。与解析器非常相似,GraphQL 将一些信息作为参数传递给该函数,即 1) 参数,2) 上下文和 3) 信息对象。以这种方式解析字段时,省略“obj”参数。
好的,那么根呢?
根对象只是作为“父字段值”提供给查询和突变的对象,这些字段与其他所有字段一样。
因此,如果您还没有为 getLocalDrivers
定义“解析”函数(例如,因为您使用 buildQuery
编译了架构),GraphQL 将使用默认解析器,并使用您传入的根对象作为“父字段值”。它看到了一个getLocalDrivers
,但如上所述,因为这是一个函数,它使用上述三个参数调用该函数。
那么这里的教训是什么?
不要使用root。
说真的。将您的架构定义为一个对象,或者如果您想使用 GraphQL 架构语言编写架构,请使用 graphql-tools -- makeExecutableSchema
使处理解析器变得更加容易。
const typeDefs = `
type Query
getLocalDrivers(location: String): [Driver]
type Driver
name: String
location: String
`
const resolvers =
Query:
getLocalDrivers: (obj, args, ctx) =>
console.log(obj, args, ctx)
const schema = makeExecutableSchema(
typeDefs,
resolvers,
)
【讨论】:
不幸的是,如果我使用来自 graphql-tools 的makeExecuteSchema
而不是 buildSchema
,我会得到相同的结果。
如果您仍在传递根值,那么您仍然会看到相同的行为。而是将解析器作为解析器对象的一部分传入。我已经用一个例子更新了我的答案。
这次我只是简单地使用 Apollo GraphQL 服务器创建了新服务器,并开始使用 makeExecuteableSchema 使其工作。不过,我的最终解决方案是暂时切换到 Express REST,因为 GraphQL 给我带来了太多问题 :-)以上是关于GraphQL 解析器参数(根、参数、上下文)的错误顺序的主要内容,如果未能解决你的问题,请参考以下文章
graphql-yoga - GraphQL 解析器参数在哪里定义和记录?