GraphQL解析器参数的顺序错误(根、参数、上下文)

GraphQL解析器参数的顺序错误(根、参数、上下文),graphql,graphql-js,express-graphql,Graphql,Graphql Js,Express Graphql,我想知道为什么我的参数似乎在GraphQL解析器中转换。我使用的是express graphql 一个解析器的示例: getLocalDrivers: async (parent, args, ctx) => { console.log(ctx); } 我已经写了文件中出现的参数名称: 但当我调试和检查对象时,args对象似乎是第一个,上下文是第二个,父/根是第三个 家长: Object {location: "020202"} args: IncomingMessag

我想知道为什么我的参数似乎在GraphQL解析器中转换。我使用的是express graphql

一个解析器的示例:

  getLocalDrivers: async (parent, args, ctx) => {
    console.log(ctx);
  }
我已经写了文件中出现的参数名称:

但当我调试和检查对象时,args对象似乎是第一个,上下文是第二个,父/根是第三个

家长:

Object {location: "020202"}
args:

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    
  }`);

如果为字段定义了
resolve
函数,GraphQL解析该字段时,将向该函数传递四个参数:

  • 父字段解析为的值(通常称为
    obj
    root
  • 该字段的参数
  • 上下文
  • 描述整个GraphQL请求的info对象
  • 如果特定字段缺少解析函数,GraphQL将使用默认的解析程序,该解析程序只搜索父字段上的属性,如果找到该属性,则使用该属性

    因此,您的
    getLocalDrivers
    查询可以返回
    Driver
    对象的数组,只要
    Driver
    对象具有
    name
    属性,那么
    name
    字段将解析为该属性的值

    巧合的是,
    Driver
    对象上的
    name
    属性也可以是一个函数。在这种情况下,GraphQL将调用该函数以获取其返回值。与解析器非常相似,GraphQL将一些信息作为参数传递给这个函数,即1)参数,2)上下文和3)信息对象。以这种方式解析字段时,“obj”参数将被忽略

    好的,那么根呢?

    根对象只是作为“父字段值”的对象,它被赋予查询和突变,这些字段与其他所有字段一样

    因此,如果尚未为
    getLocalDrivers
    定义“resolve”函数(因为您使用
    buildQuery
    编译了模式),GraphQL将使用默认的解析器,并使用传入的根对象作为“父字段值”。它会看到一个
    getLocalDrivers
    ,但如上所述,因为这是一个函数,所以它使用上述三个参数调用该函数

    那么这里的教训是什么?

    不要使用root

    真的。将模式定义为对象,或者如果要使用GraphQL模式语言编写模式,请使用--
    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工具中的
    makeExecuteSchema
    而不是
    buildSchema
    ,我会得到相同的结果。如果您仍在传递根值,则仍然会看到相同的行为。将解析程序作为解析程序对象的一部分传入。我已经用一个例子更新了我的答案。这次我只是用Apollo GraphQL服务器创建了一个新的服务器,并开始使用makeExecuteableSchema使其工作。不过,我的最终解决方案是暂时切换到ExpressREST,因为GraphQL给我带来了太多问题:-)