解析另一个子图的字段
解析不同子图中的相同实体字段
默认为正好一个子图解析您超级图模式中的每个字段,例如实体字段会出现例外@key
字段。有时,多个子图可以解析同一个实体字段,因为它们可以访问相同的数据存储。例如,库存子图和产品子图可能都可以访问存储所有产品相关数据的同一个数据库。
本指南说明了如何启用不同的子图来解析相同的字段作为性能优化。
启用子图解析相同字段
您可以选择性地使多个子图解析特定的实体字段。然后,当路由器规划查询的执行时,它会查看每个子图中可用的字段。路由器可以通过执行最少的子图来优化性能。
为此,可以使用以下指令之一:
@shareable
@provides
您使用哪个指令取决于以下逻辑:
如果您不确定您的 子图 是否总能解析出一个 字段,请查看 使用 @provides
以查看一个 子图 无法解析的示例。
确保解析器一致性
如果有多个 子图 可以解析一个 字段,请确保每个子图的 解析器 在该字段上的行为相同。否则,根据哪个子图解析了该字段,查询可能会向客户端返回不一致的结果。
当更改现有的 解析器 时,这种一致性尤其重要。如果您不同时对每个 子图进行解析器更改,客户端可能会观察到不一致的结果。
要留意的一些常见的解析器不一致行为包括:
- 返回不同的默认值
- 在相同场景下抛出不同的错误
使用 @shareable
ⓘ 注意
在使用 @shareable
之前,请查看 确保解析器一致性。
该 @shareable
指令表示多个 子图 可以解析特定的 字段。您可以这样使用它:
type Product @key(fields: "id") {id: ID!name: String! @shareableprice: Int}
type Product @key(fields: "id") {id: ID!name: String! @shareableinStock: Boolean!}
在这个例子中,市场和库存 子图 都可以解析 Product.name
。这意味着包含 Product.name
的查询有时可以减少 子图 查询的数量。
ⓘ 注意
如果某个 字段 在任何 子图中设置了 @shareable
,则必须在定义它的每个 子图中都标记为 @shareable
或 @external
。否则, 组合 将失败。
使用 @provides
ⓘ 注意
在使用 @provides
之前,请查看 确保解析器一致性。
@provides 指令表示某个特定的字段可以通过特定查询路径上的子图来解决。例如,假设库存子图可以解决Product.name
,但仅当产品是 InStockCount
的一部分时。您可以这样表示:
type InStockCount {product: Product! @provides(fields: "name")quantity: Int!}type Product @key(fields: "id") {id: ID!name: String! @externalinStock: Boolean!}
请注意库存 子图 使用了两个 指令:
- @provides 指令告诉路由器,“此 子图 可以解决由 InStockCount.product 返回的任何 Product 对象的 name。”
- @external 指令告诉路由器,“此 子图 不能解决 Product 对象的 name,除非由 @provides 指出。”
@provides
的使用规则
ⓘ 注意
违反这些规则中的任何一项都会导致组合失败。
- 如果一个 子图 @provides 一个它不能总能解决的字段,该子图必须将该字段标记为 @external 并且不得将其标记为 @shareable。
- 记住,一个 @shareable 字段始终可以由特定 子图 解决,从而消除了使用 @provides 的需要。
- 要在一个 @provides 指令中包含一个 字段,该字段必须在定义它的每个 子图 中都被标记为 @shareable 或 @external。