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

时间:2018-01-04 11:52:47

标签: reactjs graphql apollo

我有以下性质的查询

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 个答案:

答案 0 :(得分:3)

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

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

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

这里的关键点是,特定字段的解析器通常与其他解析器所执行的操作或传递给它们的信息无关。它交出了自己的父字段值,自己的参数,上下文,并期望与之合作。

但是,有一种使用info参数的解决方法。传递给info的对象很大,解析起来很复杂,但实际上包含了有关所请求查询本身的所有信息。有一些库可以帮助解析它,但你可能想把整个东西打印到控制台并且四处寻找(它非常酷!)。

使用lodash&#39; get之类的东西,然后我们可以这样做:

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

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