8. 生成检查错误
10m

概述

我们已经了解到 如何在我们的开发流程中发挥作用,以及当流程顺利进行且不产生任何错误时会发生什么。现在是时候解决不那么顺利的情况了,当针对 进行更改时会出现 组合错误

在本课程中,我们将

  • 了解 中通常遇到的错误类型
  • 了解如何在 中导航 错误
  • 了解如何使用@inaccessible

更新子图

让我们回到我们的子图团队,他们正在努力改进 Airlock。 👩🏽‍🚀 账户团队的阿喀琉斯刚刚对 accounts 的 schema 进行了一些更改,以显示主机的星系坐标。

在 schema 中,他们定义了团队商定的 GalacticCoordinates类型,并包含了两个 :纬度和经度。

subgraph-accounts/accounts.graphql
type GalacticCoordinates {
latitude: Float!
longitude: Float!
}

(你是不是已经发现错误了?别担心,我们马上就会讲到的!记住,本课的重点是当事情 在第一时间起作用时会发生什么!)

他们还在 中添加了一个新的 Host coordinates,它返回 GalacticCoordinates类型。

subgraph-accounts/accounts.graphql
type Host implements User @key(fields: "id") {
#... other Host fields
"Where the host is primarily located"
coordinates: GalacticCoordinates
}

随着这些新 schema 的增加,我们准备帮助阿喀琉斯发布这些更改,并将此功能推广到世界各地。按照我们在上一课中介绍的过程,列表中的第一件事是使用 运行本地 schema 检查。

我们将打开一个新的终端窗口,并针对 Airlock 的 staging 运行 rover subgraph check命令,其中包括文件路径和 名称参数为 accounts schema。

rover subgraph check airlock-managed-fed@staging \
--schema "accounts.graphql" \
--name accounts

我们看到这里面有些不对劲!下面是我们在终端中看到的错误信息

Checking the proposed schema for subgraph accounts against airlock-managed-fed@staging
error[E029]: Encountered 2 build errors while trying to build subgraph "accounts" into supergraph "airlock-managed-fed@staging".
Caused by:
Encountered 2 build errors while trying to build the supergraph.
INVALID_FIELD_SHARING: Non-shareable field "GalacticCoordinates.latitude" is resolved from multiple subgraphs: it is resolved from subgraphs "accounts" and "listings" and defined as non-shareable in subgraph "accounts"
INVALID_FIELD_SHARING: Non-shareable field "GalacticCoordinates.longitude" is resolved from multiple subgraphs: it is resolved from subgraphs "accounts" and "listings" and defined as non-shareable in subgraph "accounts"
The changes in the schema you proposed for subgraph accounts are incompatible with supergraph airlock-managed-fed@staging. See https://apollo.graphql.net.cn/docs/federation/errors/ for more information on resolving build errors.

错误表明 GalacticCoordinates (latitudelongitude) 在 accountslistings 中都解析过了,它们在 accounts 中被定义为不可共享的。这是 Achilles 正在研究的子图!

他们忘记给类型定义添加 @shareable ,所以让我们确保添加它。

subgraph-accounts/accounts.graphql
type GalacticCoordinates @shareable {
latitude: Float!
longitude: Float!
}

Achilles 更新了他们的架构,当我们再次运行 rover subgraph check 命令时,可以看到这个修正已经解决了 错误!

Checking the proposed schema for subgraph accounts against airlock-managed-fed@staging
Check Result:
Compared 1 schema changes against 13 operations
┌────────┬─────────────┬───────────────────────────────────────────────┐
│ Change │ Code │ Description │
├────────┼─────────────┼───────────────────────────────────────────────┤
│ PASS │ FIELD_ADDED │ type `Host`: field `coordinates` added │
└────────┴─────────────┴───────────────────────────────────────────────┘
View full details at https://studio.apollographql.com/graph/airlock-managed-fed/operationsCheck/{URL}

Achilles 继续处理他们的 ,添加必要的 方法来实现他们的架构添加。

添加新的共享字段

在将他们的更改推送到代码库之前,Achilles 会见了 Airlock 团队并得知项目模型设计已更新!除了数值坐标,用户还想了解位置的本地名称。例如,比起“83.0405 纬度和 35.2034 经度”,客人更容易理解“Z 星球”(但他们也需要知道精确坐标)。

Achilles 向 中添加了新的 GalacticCoordinates 类型: nickname,可返回 String

subgraph-accounts/accounts.graphql
type GalacticCoordinates @shareable {
latitude: Float!
longitude: Float!
nickname: String
}

太棒了!此新 已通过 AccountsAPI 服务返回,因而在 文件中无需进行其他更改。Achilles 非常期待推出此功能,他们忘记在本地再次运行 rover subgraph check 命令。相反,他们直接将更改推送到 GitHub 代码库并创建一个 PR。此操作会触发 Schema Checks 作业。

糟了,该作业失败了!

https://github.com
Screenshot of the GitHub PR with the job failed and link to the Studio Checks page

不要担心,这意味着我们的管道在问题到达生产之前就捕获到了错误!我们可以通过访问 PR 中嵌入的链接,转到 Studio 的 Checks 页面来确切调查作业失败的原因。

GraphOS 中的架构检查

Studio 中的 Checks 页面向我们展示了架构检查的结果,以便我们可以诊断错误所在。

https://studio.apollographql.com
Screenshot of the failed check in Studio Checks page

识明组成的失败点,并表明过程中出现问题的点。由于失败的意味着未生成新的将继续根据其现有有效版本的超级图模式处理请求。因此,即使在 Accounts 团队的变更不起作用的情况下,客户端使用staging 也不会发生任何错误!这给予 Accounts 团队一个机会来查看错误并在合并其 PR 之前进行修复。

以下是我们看到的错误

error[E029]: Encountered 1 build error while trying to build subgraph "accounts" into supergraph "airlock-managed-fed@staging".
Caused by:
Encountered 1 build error while trying to build the supergraph.
SATISFIABILITY_ERROR: The following supergraph API query:
mutation {
updateListing(listingId: "<any id>", listing: {}) {
listing {
coordinates {
nickname
}
}
}
}
cannot be satisfied by the subgraphs because:
- from subgraph "listings":
- cannot find field "GalacticCoordinates.nickname".
- cannot move to subgraph "accounts", which has field "GalacticCoordinates.nickname", because type "GalacticCoordinates" has no @key defined in subgraph "accounts".

我们将进一步调查错误。

在尝试编译时,我们遇到了SATISFIABILITY_ERROR。此错误意味着,表面上我们的可能看似兼容,但结果API 将至少包含一项子图无法满足的

错误消息提供了一个示例以及两点原因来解释我们的无法满足它的原因:

首先,listings 找不到 GalacticCoordinates.nickname。Achilles 仅将 nickname 添加到 accounts (其团队负责管理的子图)。listings 没有此类

其次,listings 无法将解析 nickname 的职责传递给 accounts ,因为 GalacticCoordinates并非 ,而是一种 值类型。请记住,只有实体(具有 @key 的类型)才能在多个 中解析不同的

值类型的 可能在不同 中的表现形式有所差异,但我们不能 省略 共享 。我们需要将这个 GalacticCoordinates.nickname 同时添加到 accountslistings 中。

注意:你可以详细了解共享 在值类型中呈现不同表现形式的各种方法,请参考 Apollo 共享类型文档

为了将 逐步添加到我们的各个 而不破坏 ,我们可以使用 @inaccessible

@inaccessible 指令

@inaccessible 应用于 中。每当它存在于字段上,便会将该字段从 中省略。这意味着客户端无法在 中包含该字段。这有助于我们 递增向多个 添加 ,而不会中断

请注意,我们只需要将 @inaccessible 应用于定义 其中一个 ,该 在其中被定义。

我们来使用 @inaccessible GalacticCoordinates 值类型中递增添加 nickname 。计划如下:

👩🏽‍🚀accounts 中:

  • Achilles 将添加 GalacticCoordinates.nickname 并使用 @inaccessible
  • 我们将使用自动化 CI/CD 流程,以确保这些模式添加已进入注册中心的 staging

👩🏽‍🏫 然后,在 listings 中:

  • Lisa 将添加 GalacticCoordinates.nickname 。我们不需要应用 @inaccessible,因为它已在 accounts 中解决。
  • 我们将使用自动化 CI/CD 流程,以确保这些模式添加已进入注册中心的 staging

👩🏽‍🚀使用所有使用值类型的子图中添加的新共享字段,我们最终可以返回到 accounts

  • Achilles 将 删除 @inaccessible GalacticCoordinates.nickname 。这允许该字段包含在 中并成功组合,这是因为 listings 现在包含 nickname
  • 我们将使用自动化 CI/CD 流程,以确保这些模式添加已进入注册中心的 staging

让我们开始吧!

使用 @inaccessible 指令

👩🏽‍🚀accounts 中,Achilles 将在 @inaccessible 之后添加 nickname 的返回类型。

subgraph-accounts/accounts.graphql
type GalacticCoordinates @shareable {
latitude: Float!
longitude: Float!
nickname: String @inaccessible
}

Achilles 还需要确保已在架构顶部的 中包含 import 数组。

subgraph-accounts/accounts.graphql
extend schema
@link(url: "https://specs.apollo.dev/federation/v2.7"
import: ["@key", "@shareable", "@inaccessible"])

就是这样!通过这些架构更改,让我们尝试运行本地架构检查。

rover subgraph check airlock-managed-fed@staging \
--schema "./accounts.graphql" \
--name accounts

在终端中,我们将看到

Checking the proposed schema for subgraph accounts against airlock-managed-fed@staging
Compared 1 schema changes against 16 operations
┌────────┬─────────────┬────────────────────────────────────────┐
│ Change │ Code │ Description │
├────────┼─────────────┼────────────────────────────────────────┤
│ PASS │ FIELD_ADDED │ type `Host`: field `coordinates` added │
└────────┴─────────────┴────────────────────────────────────────┘

太棒了,检查通过,没有错误!添加的 nickname 未显示在检查中,这是因为它当前被标记为 @inaccessible。我们将向 GitHub 推送更改,并让 CI 运行其 。当这些检查通过时,我们可以合并 PR,自动触发部署过程,并将更改部署到 accounts 在 Heroku 中的暂存环境,以及 Apollo 模式注册表中的 Airlock 图 staging

将新的共享字段添加到 listings 子图

👩🏽‍🏫 返回 listings ,Lisa 会向 GalacticCoordinates 值类型添加 nickname

subgraph-listings/listings.graphql
type GalacticCoordinates @shareable {
latitude: Float!
longitude: Float!
nickname: String
}

此新 已由 ListingsAPI 服务返回,因此 文件中无需进行任何其他更改。我们可以遵循 CI/CD 进程,将这些模式更改提交到 listings 在 Heroku 中的暂存环境以及 Apollo 模式注册表中的 Airlock 图表 暂存

删除 @inaccessible 指令

👩🏽‍🚀 由于 GalacticCoordinates.nickname 在每个使用值类型的 中定义,Achilles 已准备好从 GalacticCoordinates.nickname 中删除 @inaccessible

subgraph-accounts/accounts.graphql
type GalacticCoordinates @shareable {
latitude: Float!
longitude: Float!
nickname: String
}

就是这样!现在,我们可以遵循我们已经习惯的 CI/CD 进程,并将这些模式更改提交到 暂存

这次模式检查将显示 nickname 已成功添加:

Checking the proposed schema for subgraph accounts against airlock-managed-fed@staging
Compared 1 schema changes against 16 operations
┌────────┬─────────────┬────────────────────────────────────────────────────┐
│ Change │ Code │ Description │
├────────┼─────────────┼────────────────────────────────────────────────────┤
│ PASS │ FIELD_ADDED │ type `GalacticCoordinates`: field `nickname` added │
└────────┴─────────────┴────────────────────────────────────────────────────┘

在验证暂存环境中的所有内容正常后,我们就可以部署到生产环境了!我们在前面的课程中已经介绍了这些步骤,因此如果你需要复习,可以随时参考该部分内容。

我们通过向坐标添加一个熟悉的昵称来改进了 Galactic Coordinates 项目。此功能已正式面向世界发布,客户端即可使用!

实践

以下哪些关于构建检查的陈述是正确的?

关键要点

  • 我们使用 rover subgraph check 命令执行 本地。
  • 的输出可以在 Studio 中查看,也可以使用 在本地查看。
  • 要向值类型添加一个新的 ,我们应首先将 @inaccessible 应用到 。然后,我们可以将新字段逐步添加到定义值类型的每个 。最后,我们可以删除 @inaccessible 将正式成为 的一部分。

下一步

在下一课中,我们将学习 检查,以及 如何根据客户端从图形中获取数据的历史方式验证建议的架构更改。

上页

分享你对本课程的问题和评论

你的反馈有助于我们不断改进!如遇困难或对课程内容感到疑惑,请告知我们,我们会帮助你解决问题。所有评论均为公开,必须遵守 Apollo 行为准则。请注意,已解决或已被解决的评论将被移除。

您需要一个 GitHub 帐号才能在下方发帖。没有 GitHub 帐号? 请转到我们的 Odyssey 论坛发帖。