我在 graphql 中有一个深度嵌套的类型,我用图形不同部分的内容来解析它(没有直接的父级->子级)
解析器中的某些子属性需要来自父级的属性(但有时不是直接位于上面的父级),因此我将此对象传递到解析器上下文中,以便叶节点可以访问它。
示例:
我的数据库有很多产品项目
{
"products": [
{
"id": "1",
"name": "product-1",
"options": [
{
"id": "colour-gray",
"items": [
{
"id": "not-selected",
"name": "not selected",
"price": 0
},
{
"id": "selected",
"name": "selected",
"price": 10
}
]
},
{
"id": "colour-red",
"items": [
{
"id": "not-selected",
"name": "not selected",
"price": 0
},
{
"id": "selected",
"name": "selected",
"price": 10
}
]
}
]
},
{
"id": "2",
"name": "product-1",
"options": [
{
"id": "colour-gray",
"items": [
{
"id": "not-selected",
"name": "not selected",
"price": 0
},
{
"id": "selected",
"name": "selected",
"price": 30
}
]
},
{
"id": "colour-red",
"items": [
{
"id": "not-selected",
"name": "not selected",
"price": 0
},
{
"id": "selected",
"name": "selected",
"price": 25
}
]
}
]
}
]
}
我有一个产品解析器,但我需要动态添加有关选项的内容并显示价格等内容,但这些选项取决于产品 ID,
最终结果是这样的:
{
"id": "colour-gray",
"items": [
{
"id": "not-selected",
"name": "not selected",
"price": 0,
"content": "No cost added"
},
{
"id": "selected",
"name": "selected",
"price": 10,
"content": "only today it will cost 10, at discounted price for product-1"
}
]
}
我有一个填充产品的服务,还有一个单独提供内容的服务,两者没有连接,这一切都是通过图表完成的。
为了解决填充内容的任何内容都不知道 ProductId 的事实,我们将其放入上下文对象中。
但是我知道上下文对象在请求的生命周期内共享给所有解析器。
现在我的问题是:
我在文档中找不到 gql 如何解析图表的任何地方。如果它一次从图表顶部一直填充一个,或者它可以尝试同时执行操作。
如有任何帮助,我们将不胜感激。
TLDR:是的。
然而,通常情况下,向子对象添加值以便将它们传递给孙子对象会更简单。
您的模型看起来像:
type Product {
id: ID!
name: String
options: [Option]
}
type Option {
id: ID!
items: [Item]
}
type Item {
id: ID!
name: String
price: Number
content: String
}
面临的挑战是,要正确解决
Item
,您需要了解id
的祖父母Product
。
我建议您在解析
id
时包含产品的 options
- 这将导致它传递给 Item
解析器。
options
类型的Product
解析器自然会获得父产品的id
。
options: ({ id:productId },args,context) => database('options').where({ productId })
我在这里使用 knexjs 风格的 ORM 语法,但它将基于您使用的任何数据库和 ORM。
这里我们只是返回
options
表中属于相关产品的所有列 无论它们是否包含在 Option
的 GraphQL 类型定义中。这意味着 productId
列将被包含在内。
现在,当 GraphQL 解析
items
类型下的 Option
字段时,parent
字段将包含该 productId
字段 ,即使它最终会从最终结果中删除!
items: ( { id:optionId, productId }, args, context ) => database('items').where({ optionId, productId })