我有以下性质的查询
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的’resolver’无法看到或接收rootargs.name来执行这种过滤。
解析功能签名包括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。
makeExecutableSchema
这里的关键点是,特定字段的解析器通常与其他解析器的作用或传递给他们的信息无关。它拥有自己的父字段值,自变量,上下文,并有望与此一起使用。
但是,有一种使用该info参数的解决方法。传递给info的对象很大,解析起来可能很复杂,但实际上包含有关所请求查询本身的所有信息。有一些库可以帮助您解析它,但是您可能希望将整个内容打印出来以进行控制台和四处探究(这很酷!)。
info
使用lodash’s这样的东西get,我们可以做到:
get
const category1id = get(info, 'operation.selectionSet.selections[0].arguments[0].value.value')
并在查询中利用该值。上面的内容非常脆弱,因为它假设您的请求仅包含一个查询,并且该Category1字段上只有一个参数。在实践中,您可能想Array.find按名称利用和查找字段/参数,但这应该为您提供一个起点。
Category1
Array.find