加入我们,于10月8日至10日在纽约市参加GraphQL联邦和API平台工程最新技巧、趋势和新闻学习活动。加入2024年纽约市的GraphQL峰会
文档
免费开始

贡献和参考实体字段

跨子图贡献和参考实体字段


在联合架构中架构中,单个可以向共享实体贡献并引用。本指南解释了子图如何协同工作以构建统一的模式,并通过添加和计算字段以及不添加字段而仅引用实体的示例。

贡献实体字段

任何数量的不同子图可以向实体定义添加字段。以下示例中,Product 实体:

产品子图
type Product @key(fields: "id") {
id: ID!
name: String!
price: Int
}
库存子图
type Product @key(fields: "id") {
id: ID!
inStock: Boolean!
}

默认情况下,每个都必须贡献不同的字段,但是有一个重要的例外,就是@key 字段。如果多个子图尝试贡献相同的字段,就会发生一个错误。

贡献字段的每个子图必须为该实体定义一个引用解析器。

贡献计算实体字段

您可以从其他实体字段计算字段定义实体字段,即使是不同的子图解析这些字段的情况。

例如,这个Shipping子图Product实体添加了一个shippingEstimate 字段。此字段基于产品的大小和重量进行计算,而Product子图定义了这些属性:

Shipping子图
type Product @key(fields: "id") {
id: ID!
size: Int @external
weight: Int @external
shippingEstimate: String @requires(fields: "size weight")
}
产品子图
type Product @key(fields: "id") {
id: ID!
name: String!
price: Int
size: Int
weight: Int
}

注意Shipping子图使用了两个

  • @requires 指令指示需要从其他子图获取哪些字段。
  • @external 指令应用于类型定义中的所需字段。
    • 此指令告诉 ,“这个子图知道这些字段存在,但它无法自行解析它们。”

路由器如何处理计算实体字段

在前面的例子中,如果查询请求产品的shippingEstimate,路由器会做以下操作:

  1. 它会查询Product子图以获得产品的大小和重量。
  2. 它会查询Shipping子图以获得产品的shippingEstimate
  • 它会包含传递给shippingEstimate解析器的Product对象的大小和重量:

    resolvers.js
    {
    Product: {
    shippingEstimate(product) {
    return computeShippingEstimate(product.id, product.size, product.weight);
    }
    }
    }

使用@requires与包含子字段的对象

如果一个计算字段 @requires需要一个返回对象类型的字段,你还需要指定该对象哪些子字段是必需的。你可以使用以下语法列出这些子字段:

Shipping子图
type Product @key(fields: "id") {
id: ID!
dimensions: ProductDimensions @external
shippingEstimate: String @requires(fields: "dimensions { size weight }")
}

在此前的示例修改中,sizeweight现在是ProductDimensions对象中的子字段。产品和运输子图必须都定义ProductDimensions类型,这才能有效。

使用@requires处理带参数的字段
2.1.2

从Federation v2.1.2版本开始,@requires指令可以包含:

Shipping子图
type Product @key(fields: "id") {
id: ID!
weight(units: String): Int @external
shippingEstimate: String @requires(fields: "weight(units:\"KILOGRAMS\")")
}

以下规则适用

  • 路由器在其查询中为定义所需字段的子图提供指定的值。
  • 每个指定的值是静态的;路由器始终提供相同的值。
  • 您可以省略可空参数的值。对于非可空参数,您必须提供值。
  • 如果您在自己的子图模式中定义了SDL文件而不是按程序方式定义,您必须使用反斜杠转义字符串和枚举值的引号(如上所示)。

引用实体而不提供字段

您的子图可以使用一个实体作为字段的返回类型,而不向该实体提供任何字段。

例如,看看产品子图中的这个Product实体:

产品子图
type Product @key(fields: "id") {
id: ID!
name: String!
price: Int
}

假设您想创建一个包含以下Review类型的Reviews子图:

Reviews子图
type Review {
product: Product!
score: Int!
}

虽然这是可能的,但当前的Reviews子图模式无效,因为它没有定义Product实体。

要修复此问题,请将实体原型添加到Product子图,如下所示:

Reviews子图
type Review {
product: Product!
score: Int!
}
type Product @key(fields: "id", resolvable: false) {
id: ID!
}

占位符定义仅包括@key实体字段。在这种情况下,Product类型定义仅包括id字段。它还在@key指令中包含resolvable: false,以表示此子图没有为Product实体定义引用解析器。

上一页
定义高级键
下一页
解析另一个子图的字段
评价文章评价在 GitHub 上编辑编辑论坛Discord

©2024Apollo Graph Inc.(商业名称:Apollo GraphQL)。

隐私政策

公司