如何在嵌套查询的解析器函数中传递根参数?

IT技术 reactjs graphql apollo
2021-05-15 17:26:00

我有以下性质的查询

Category1(name: $cat1){
   Category2(secondName: $cat2){
      secondName
    }}

我的架构是这样的:

const Query = new GraphQLObjectType({
name: 'Query',
fields: {
    Category1: {
        type: new GraphQLList(Category1Type),
        args: { name },
        resolve: resolveCategory1
    }}
})

然后 Category1Type 定义为:

const Category1Type = new GraphQLObjectType({
    name: 'Category1',
    description: '<>',
    fields: () => ({
        name: { type: GraphQLString },
        category2: {
            type: new GraphQLList(CategoryType2),
            args: { secondName },
            resolve: resolveCategory2
        }
    })
});

为简单起见,假设 category2 是这样的:

const Category2Type = new GraphQLObjectType({
    name: 'Category2',
    description: '<>',
    fields: () => ({
        name: { type: GraphQLString },
    })
});

现在我想使用过滤选项获取 Category1 下的所有 Category2 项目,如下所示:

Category1(name: $name){
   name
   category2(name: $name){
      name 
}}

我的解析器定义如下:

    # Category1 resolver
    function cat1resolve (root, args) {
return SELECT * from data WHERE category1_name = args.name
}

    # Category2 resolver
    function cat2Resolve (root, args) {
return SELECT * from data WHERE category1_name = rootargs.name and categort2_name = args.secondName }

现在的问题是 cat2Resolve 的“解析器”无法看到或接收 rootargs.name 来让我进行这种过滤。

1个回答

解析函数签名包括 4 个参数。来自 Apollo 的文档

  1. obj:包含从父字段的解析器返回的结果的对象,或者,在顶级查询字段的情况下,从服务器配置传递的 rootValue。此参数启用 GraphQL 查询的嵌套性质。
  2. args:带有传递到查询字段的参数的对象。例如,如果使用 author(name: "Ada") 调用该字段,则 args 对象将是:{ "name": "Ada" }。
  3. 上下文:这是特定查询中所有解析器共享的对象,用于包含每个请求的状态,包括身份验证信息、数据加载器实例以及在解析查询时应考虑的任何其他内容。如果您使用 Apollo Server,请阅读设置文档中有关如何设置上下文的信息。
  4. info:该参数只应在高级情况下使用,但它包含有关查询执行状态的信息,包括字段名称、从根到字段的路径等。它仅记录在 GraphQL.js 源代码中。

注意:这些文档适用于 graphql-tools makeExecutableSchema(我强烈推荐),但同样适用于普通的旧 GraphQL.JS。

这里的关键点是特定字段的解析器通常与其他解析器做什么或传递给它们的信息无关。它传递了它自己的父字段值、它自己的参数、上下文并期望使用它。

但是,有一种使用该info参数的解决方法传递给 info 的对象很大,解析起来可能很复杂,但实际上包含有关所请求查询本身的所有信息。有一些库可以帮助解析它,但是您可能想要打印整个内容以进行控制台和浏览(这很酷!)。

使用类似 lodash 的东西get,我们可以这样做:

const category1id = get(info, 'operation.selectionSet.selections[0].arguments[0].value.value')

并在您的查询中使用该值。上面的内容非常脆弱,因为它假设您的请求仅包含一个查询,并且您在该Category1字段上只有一个参数在实践中,您可能希望Array.find按名称使用和查找字段/参数,但这应该为您提供一个起点。