首页 > 解决方案 > GraphQL - 何时使用解析器或带有递归和规范化数据的参数?

问题描述

我正在使用一个非常大的标准化和递归对象。我想获取所有递归项的列表。我应该使用参数还是自定义解析器?

我的对象看起来像:

{
  products: [{
    product_id: "car",
    bundle_id: 5
  },{
    product_id: "door"
    bundle_id: 6
  },
  { product_id: "wheel" },
  { product_id: "metal" },
  { product_id: "glass" }],

  bundles: [{
    bundle_id: 5,
    options: [{product_id: "door"},{product_id: "wheel"}]
  },
  {
    bundle_id: 6,
    options: [{product_id: "metal"},{product_id: "glass"}]
  }]

}

您可能会注意到“汽车”是bundle具有 adoor和 a 的 a wheel。“门”也是一个bundlemetalglass。这种结构可以无限递归。也就是说,一个捆绑包下可以有无限多的捆绑包产品。

我想获取捆绑产品的所有产品列表(例如:“汽车”)。最好的方法是什么?

我看到两个选项。

第一个选项 - 使用自定义解析器,例如child_products,它将递归并解析为所有子元素的平面数组:

products(product_id: "car") {
  product_id
  bundle {
    options {
      product_id
    }
  }
  child_products {
    product_id
    bundle {
      options {
        product_id
      }
    }
  }
}

第二个选项 - 使用指定包含所有子项的参数:

products(product_id: "car", include_children: true) {
  product_id
  bundle {
    options {
      product_id
    }
  }
}

我将构建一个 JS 库,它可以获取产品和选项数组并构建嵌套结构。请让我知道您认为正确的方法。谢谢!

标签: graphql

解决方案


您不应该需要这样的参数,include_children因为客户端的查询足以确定是否包括节点——如果客户端不需要节点,它可以简单地省略适当的字段。

基于提供的 JSON 对象,我期望一个看起来像这样的模式:

type Query {
  product(id: ID!): Product
}

type Product {
  id: ID!
  bundle: Bundle
}

type Bundle {
  id: ID!
  options: [Product!]!
}

这将使您可以进行如下查询:

query {
  product(id: "car") {
    id
    bundle {
      options {
        id
        bundle {
          id
          # and so on...
        }
      }
    }
  }
}

此查询的实际深度将取决于客户的需要。像这样的递归类型定义确实存在可能的攻击向量,因此您还应该考虑使用类似graphql-depth-limitgraphql-query-complexity的库。


推荐阅读