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

Posted

技术标签:

【中文标题】如何在嵌套查询的解析器函数中传递根参数?【英文标题】:How to pass root parameters in the resolver function of a nested query? 【发布时间】:2018-06-14 03:35:52 【问题描述】:

我有以下性质的查询

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,我无法进行此类过滤。

【问题讨论】:

听起来您的架构有问题。请更新您的问题以包含架构,或至少包含与这三种类型相关的部分。 感谢您更新问题 :) 所以澄清一下,您面临的问题不是您之前提到的错误,而是 Category2 的解析器没有按预期工作?包含实际的解析器代码以及运行查询时看到的意外行为会对您有所帮助。 @DanielRearden 我试图进一步解释确切的操作 【参考方案1】:

解析函数签名包括 4 个参数。来自阿波罗的docs:

    obj:包含解析器在父字段上返回的结果的对象,或者,在***查询字段的情况下, 从服务器配置传递的 rootValue。这个论点使 GraphQL 查询的嵌套性质。 args:带有参数的对象传递到查询中的字段中。例如,如果使用 author(name: "Ada") 调用该字段, args 对象将是: "name": "Ada" 。 context:这是特定查询中所有解析器共享的对象,用于包含每个请求的状态,包括 身份验证信息、数据加载器实例和其他任何内容 解决查询时应考虑到这一点。如果你是 使用 Apollo Server,了解如何在设置中设置上下文 文档。 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 并按名称查找字段/参数,但这应该为您提供一个起点。

【讨论】:

以上是关于如何在嵌套查询的解析器函数中传递根参数?的主要内容,如果未能解决你的问题,请参考以下文章

如何处理 GraphQL 中的嵌套输入

TypeORM Apollo 嵌套查询解析器

在 GraphQL 中将参数从根传递到子查询

Apollo Server:将参数传递给嵌套解析器

使用 appsync 解析器、aws dymaodb 的嵌套查询

如何解决 graphql 查询中的嵌套项