我想知道为什么我的论点似乎在我的GraphQL解析器中切换了。我使用的是express-graphql。
一个解析器的示例:
getLocalDrivers: async (parent, args, ctx) => {
console.log(ctx);
}
我已经在文档中显示了参数名称:http://graphql.org/learn/execution/
但是当我调试和检查对象时,似乎args对象是1st,上下文是2nd,而parent / root是3rd。
父:
Object {location: "020202"}
args:
IncomingMessage {_readableState: ReadableState, readable: false, domain: null, …}
上下文:
Object {fieldName: "getLocalDrivers", fieldNodes: ....
一些服务器代码:
app.use(
"/graphql",
graphqlHTTP({
schema,
graphiql: true,
rootValue: rootResolver
})
);
我的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
}`);
答案 0 :(得分:2)
如果为某个字段定义了resolve
函数,当GraphQL解析该字段时,它会将四个参数传递给该函数:
obj
或root
)如果特定字段没有解析函数,GraphQL将使用默认解析器,它只是在父字段上搜索属性并在找到它时使用它。
因此,您的getLocalDrivers
查询可以返回Driver
个对象的数组,只要Driver
对象具有name
属性,name
< em> field 将解析为该属性的值。
巧合的是,name
对象上的Driver
属性也可以是一个函数。在这种情况下,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,
})