在 graphql 解析器中使用上下文将变量传递给嵌套类型是否安全

问题描述 投票:0回答:1

我在 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 的事实,我们将其放入上下文对象中。

但是我知道上下文对象在请求的生命周期内共享给所有解析器。

现在我的问题是:

  • 虽然这似乎有效,但我不完全确定这是否只是巧合。
  • 如果我开始异步解决这些问题,就会崩溃。 -如果 graphql 发生升级会导致它崩溃。
  • 这是一种不好的做法吗?如果是的话,如何解析需要来自图形上方(来自其直接父级上方的一层)上下文的叶对象

我在文档中找不到 gql 如何解析图表的任何地方。如果它一次从图表顶部一直填充一个,或者它可以尝试同时执行操作。

如有任何帮助,我们将不胜感激。

graphql apollo graphql-yoga
1个回答
0
投票

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 })
© www.soinside.com 2019 - 2024. All rights reserved.