Cod*_*rBC 4 apollo reactjs graphql
我有以下性质的查询
Category1(name: $cat1){
Category2(secondName: $cat2){
secondName
}}
Run Code Online (Sandbox Code Playgroud)
我的架构是这样的:
const Query = new GraphQLObjectType({
name: 'Query',
fields: {
Category1: {
type: new GraphQLList(Category1Type),
args: { name },
resolve: resolveCategory1
}}
})
Run Code Online (Sandbox Code Playgroud)
然后 Category1Type 定义为:
const Category1Type = new GraphQLObjectType({
name: 'Category1',
description: '<>',
fields: () => ({
name: { type: GraphQLString },
category2: {
type: new GraphQLList(CategoryType2),
args: { secondName },
resolve: resolveCategory2
}
})
});
Run Code Online (Sandbox Code Playgroud)
为简单起见,假设 category2 是这样的:
const Category2Type = new GraphQLObjectType({
name: 'Category2',
description: '<>',
fields: () => ({
name: { type: GraphQLString },
})
});
Run Code Online (Sandbox Code Playgroud)
现在我想使用过滤选项获取 Category1 下的所有 Category2 项目,如下所示:
Category1(name: $name){
name
category2(name: $name){
name
}}
Run Code Online (Sandbox Code Playgroud)
我的解析器定义如下:
# 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 }
Run Code Online (Sandbox Code Playgroud)
现在的问题是 cat2Resolve 的“解析器”无法看到或接收 rootargs.name 来让我进行这种过滤。
解析函数签名包括 4 个参数。从阿波罗的文档:
- obj:包含从父字段的解析器返回的结果的对象,或者,在顶级查询字段的情况下,从服务器配置传递的 rootValue。此参数启用 GraphQL 查询的嵌套性质。
- args:带有传递到查询字段中的参数的对象。例如,如果使用 author(name: "Ada") 调用该字段,则 args 对象将是:{ "name": "Ada" }。
- context: This is an object shared by all resolvers in a particular query, and is used to contain per-request state, including authentication information, dataloader instances, and anything else that should be taken into account when resolving the query. If you’re using Apollo Server, read about how to set the context in the setup documentation.
- info: This argument should only be used in advanced cases, but it contains information about the execution state of the query, including the field name, path to the field from the root, and more. It’s only documented in the GraphQL.js source code.
Note: These docs are for graphql-tools' makeExecutableSchema
(which I highly recommend) but the same applies to plain old GraphQL.JS.
The key point here is that a resolver for a particular field is generally agnostic to what other resolvers do or what information is passed to them. It's handed its own parent field value, its own arguments, the context and expected to work with that.
However, there is a workaround utilizing the info
parameter. The object passed to info is huge and can be complicated to parse, but contains virtually all the information about the requested query itself. There are libraries out to help with parsing it, but you may want to print the whole thing to console and poke around (it's pretty cool!).
Using something like lodash's get
, we can then do:
const category1id = get(info, 'operation.selectionSet.selections[0].arguments[0].value.value')
Run Code Online (Sandbox Code Playgroud)
and utilize that value inside your query. The above is pretty fragile, since it assumes your request only contains the one query, and you only have one argument on the Category1
field. In practice, you'd probably want to utilize Array.find
and look up the fields/arguments by name, but this should give you a starting point.
归档时间: |
|
查看次数: |
3019 次 |
最近记录: |