GraphQL解析器参数的错误顺序(root,args,context)

时间:2018-02-05 19:25:59

标签: graphql graphql-js express-graphql

我想知道为什么我的论点似乎在我的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    
  }`);

1 个答案:

答案 0 :(得分:2)

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

  1. 父字段解析为的值(通常称为objroot
  2. 该字段的参数
  3. 上下文
  4. 描述整个GraphQL请求的info对象
  5. 如果特定字段没有解析函数,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,
    })