模式检查
验证您的图模式提出更改的安全性
对您的图's schema (such as removing a field or type) might break one of your application's clients. GraphOS schema checks help you identify breaking changes before you make them. They can also help you identify when a potentially dangerous change is, in fact, safe.
您可以在 GraphOS Studio 中的 ```schema checks``` 面页查看 schema checks 的结果,从而帮助您在演变图时做出明智的决定:
除...合约检查, schema checks 都是 所有 Apollo 计划 的一部分。
检查类型
GraphOS 可以执行以下类型的schema checks:
组成检查: 对于 超级图,验证您对 子图模式所做的更改是否与其他子图模式成功组合。
操作检查: 将您提出的模式更改与历史 操作进行比较,以验证更改是否破坏了您的任何 graph's 活跃客户端。
检查器检查: 分析您提出的模式更改是否违反了格式规则和其他 GraphQL最佳实践。
合约检查(仅限企业版): 在对 schema检查进行源变体时的合约检查,同时检查您提出的模式更改是否破坏了任何下游 合约变体。
本文大部分涵盖了 组成和 操作检查。
- 有关检查器的详细信息,请参阅 Schema linting。
- 有关提案检查的详细信息,请参阅 Schema proposals check configuration。
- 有关合约检查的详细信息,请参阅 Contract checks。
先决条件
要启用 schema检查,请执行以下操作(如果您尚未这样做):
请确保您已将所有 子图模式发布到 GraphOS,并且这些模式是最新的。
对于 operation检查,请确保您的 supergraph正在向 GraphOS 发送操作指标。GraphOS 使用历史指标来确定潜在的更改是否安全。
⚠️ 注意
如果 GraphOS 缺乏 operation指标进行比较,所有潜在的更改都会导致检查失败。
- 如果您有一个 云超级图,您的 路由器将自动报告指标。
- 请参阅其他图形类型的设置。
安装 Rover CLI在您的开发环境中,并将其通过 GraphOS 进行身份验证。
运行您的第一次检查
假设您已对某个子图模式进行本地更改。完成先决条件后,您可以使用rover subgraph check
命令对这些更改运行模式检查。
ⓘ 注意
如果您有一个单本图(不建议使用),请使用rover graph
命令而不是rover subgraph
命令。
以下是rover subgraph check
命令的示例:
rover subgraph check docs-example-graph@main --name products --schema ./schema.graphql
它需要以下内容
您的已注册图的graph ref,是一个具有
graph-id@variant-name
格式(例如,docs-example-graph@main
)。这可以在 GraphOS Studio 中GraphOS的的 README 页面上找到。您模式的本地产版本。在上述命令中,模式是通过
.graphql
文件提供的。如果您的模式不在独立的
.graphql
文件中,您可以在本地运行您的GraphQL 服务器,并通过rover graph introspect
直接从其获取模式,如下所示:rover subgraph introspect https://127.0.0.1:4000 | rover subgraph check docs-example-graph@main --name products --schema -
尝试在本地版本的模式中更改一些内容,看看会发生什么!如果一切设置正确,命令的输出类似于检查响应中显示的输出。
检查生命周期
运行 rover subgraph check
时:
- GraphOS会在您的本地模式与检查的变体 发布的模式之间生成差异。
- GraphOS将使用该差异来确定更改是否会影响您在超图中执行的任何操作,这些操作是在一个自定义时间窗口内(默认情况下为过去七天)
- GraphOS会返回差异,以及受更改影响的操作列表。
- Rover会打印出检查结果,如果发现至少有一个破坏性更改,则返回非零退出码。
检查响应
运行 rover subgraph check
会输出所有检测到的模式更改的差异,并突出显示破坏性更改:
$ rover subgraph check docs-example-graph@current --subgraph products --schema ./schema.graphqlValidated the proposed subgraph against metrics from docs-example-graph@currentCompared 1 schema changes against 24 operations┌────────┬────────────────────┬─────────────────────────────────────────────────────────┐│ Change │ Code │ Description │├────────┼────────────────────┼─────────────────────────────────────────────────────────┤│ PASS │ FIELD_CHANGED_TYPE │ field `Query.books`: type `[Book]` changed to `[Book!]` │└────────┴────────────────────┴─────────────────────────────────────────────────────────┘View full details at https://studio.apollographql.com/service/docs-example-graph/checks/<DETAILS>
对模式的所有更改都被标记为PASS
或FAIL
。
ⓘ 注意
由于破坏性更改通过分析最近的操作来检测,您的图库必须在GraphOS中报告指标,以便模式检查工作。如果没有比较的操作指标,所有潜在的危险模式更改都被标记为FAIL
。
如果任何检查失败,rover subgraph check
命令将返回非零结果。
输出还包括一个Studio URL,该URL提供了有关更改及其对现有客户和操作影响的全部详细信息:
如果您已将模式检查与GitHub PR集成,GitHub检查中的Details链接将带您访问此详情页面。
如果您在Git存储库内运行检查,rover subgraph check
会将提交哈希及其作者发送给GraphOS以在检查中显示。如果您尚未将模式检查与GitHub集成,作者将显示为Unknown。如果您想覆盖作者、提交或其他值,您可以在Rover中设置环境变量来做到这一点。
重新运行检查
您可以再次从GraphOS Studio运行检查。选择检查并点击重新运行检查。
当您重新运行检查时,新运行将使用当前的检查配置选项,而不管最初运行的配置如何。同样,新运行的窗口时间基于当前时间,而不是原始检查运行时的时间。
新运行的检查包括对已排除或包含的客户所做的任何更改,以及标记为安全或忽略的操作。
ⓘ 注意
如果您已经将模式检查集成到您的GitHub PR中,重复运行检查还会更新GitHub中检查的状态。
组合检查
当你运行rover subgraph check
时,GraphOS组合检查会在执行任何其他检查之前进行。组合检查会验证你对子图架构所做的更改是否是有效的GraphQL定义,并且是否与你的其他子图架构兼容,从而可以组合成你的router的超级图架构。
如果组合检查失败,Studio不会对提供的架构执行其他检查。
从graph的Checks页面在GraphOS Studio中,您可以点击特定的组合检查以查看其结果。如果组合成功,您可以看到组合的supergraph架构。无论成功与否,您都可以查看建议的子图架构。
操作检查
如果组合检查成功,GraphOS然后使用你的graph历史客户端操作数据通过操作检查验证模式更改。操作检查会使用你的graph历史客户端操作数据来确定任何客户端是否会因建议的模式更改而受到负面影响。例如,操作检查会标记一个更改,该更改删除了多个客户端在操作中使用的字段。
覆盖标记的更改
有时,架构检查可能会标记您知道是安全的更改。例如,当您确信客户端永远不会为字段提供null值时,您可能会将输入类型的字段从可空更改为先不为空(通常是一个破坏性更改)。
您可以逐个操作覆盖标记的更改或更新您的检查设置以忽略某些特定类型的更改。
按操作覆盖更改
组织管理员和Graph管理员可以在GraphOS Studio中以逐个操作的方式覆盖标记的更改。从关联的检查详情页面,选择标记操作下的覆盖下拉菜单:
对于带有标记更改的操作,您可以以下方式覆盖这些更改:
- 将变更标记为安全: 在此情况下,模式检查不会在任何未来的执行中对这些更改进行标记。这实际上“批准”了这些更改以便进行操作。
- 如果未来的检查检测到经过批准的更改和新不安全的操作更改,则新不安全的更改将被标记。
- 忽略操作: 在这种情况下,模式检查将在任何未来的执行中检查所有更改时完全忽略该操作。
- 当您知道某个操作仅来自您不积极支持的客户端或客户端版本时,此选项很有用。
您可以从任何被覆盖的操作上出现的撤销横幅撤消覆盖。
忽略条件设置
您可以通过更新检查设置,使得操作检查不会标记以下类型的更改:
当没有操作时忽略破坏性更改: 启用此设置将在对零操作运行操作检查时忽略任何潜在的破坏性更改。
忽略默认值更改: 启用此设置将忽略任何对默认值的更改。
ⓘ 注意
此设置忽略默认值更改,但不忽略默认值删除。
您可以从变体的配置选项卡中启用这些设置。了解配置模式检查页面上的其他检查设置
代码检查器检查
有关代码检查器的更多信息,请参阅模式检查有关
建议检查
此功能仅适用于 GraphOS企业计划.
通过免费注册 企业试用版.
有关建议检查的更多信息,请参阅模式建议文档
合约检查
此功能仅适用于 GraphOS企业计划.
通过免费注册 企业试用版.
有关合约检查的更多信息,请参阅合约文档
在CI中使用
模式检查特别适用于将其添加到您的CI管道(例如Jenkins或CircleCI)。通过这样做,您可以在团队拉取请求中直接获取检查结果。
我们建议为每个您想要验证更改的方案变体(生产、预览等)定义一个单独的CI作业。
身份验证Rover
“rover config auth”命令是交互式的,这意味着你不应该在CI环境中使用它。相反,你可以在CI中通过设置
APOLLO_KEY
环境变量来通过工作室认证Rover。有关详细信息,请参阅配置Rover。
示例配置
以下配置为CircleCI管道定义了一个模式检查作业。你的配置的语法因CI工具而异,但作业的步骤是相同的。
version: 2jobs:# ...other jobs...# Define a separate job for each environment you validate against.check_against_staging:docker:- image: circleci/node:12steps:- checkout- run: npm install# Start the GraphQL server. If a different command is used to# start the server, use it in place of `npm start` here.- run:name: Starting servercommand: npm startbackground: true# Make sure the server has enough time to start up before running# commands against it.- run: sleep 5# In CI environments, this command authenticates via the `APOLLO_KEY`# environment variable.- run: rover subgraph check docs-example-graph@current --name products --schema ./schema.graphql
与GitHub集成
如果你使用GitHub,你可以在GitHub市场中安装Apollo Studio GitHub应用。此应用将使GraphOS在每个调用rover subgraph check
时将webhook发送回你的GitHub项目,为你的拉取请求提供内置的通过/失败状态检查:
与其他版本控制服务集成
如果你使用GitHub Enterprise,Bitbucket或其他版本控制服务,我们建议设置CI工具,在每个拉取请求中发表有关模式检查结果的评论。通过直接在PR中显示模式差异和破坏性更改,你可以避免在CI日志中查找检查失败的原因。
自定义检查
请参阅配置模式检查。
模式更改的类型
对模式的所有更改都不一定是破坏性的更改。增量更改(比如向类型中添加一个字段)通常是安全的,不会影响活动客户端。删除和修改(比如删除字段或更改返回类型),然而,可能会破坏使用受影响类型和字段的客户端。
可能破坏性的更改
ⓘ 注意
你可以使用忽略条件设置来忽略在没有流量的变体上检测到的所有可能的破坏性更改。
删除
这些更改删除了一个模式元素。如果一个操作正在使用要删除的元素,则该操作将开始返回错误。
名称 | 描述 |
---|---|
FIELD_REMOVED | 至少有一个操作使用了被删除的字段。 |
TYPE_REMOVED | 至少被一个操作使用的标量或对象已被删除。 |
ARG_REMOVED | 至少被一个操作使用的参数从一个字段中删除。 |
TYPE_REMOVED_FROM_UNION | 一个类型被从被至少一个操作使用的联合中删除。 |
FIELD_REMOVED_FROM_INPUT_OBJECT | 一个字段从被至少一个操作使用的输入类型中删除。该字段在下另一个字段中被引用,而这个字段至少被一个操作使用。 |
VALUE_REMOVED_FROM_ENUM | 一个值被从至少一个操作使用的枚举中删除。 |
TYPE_REMOVED_FROM_INTERFACE | 从一个至少被一个操作使用的接口中删除了一个对象。 |
必需参数的增加
这些更改向架构元素中添加了一个必需的输入。如果操作正在积极使用您的图中的元素,并且没有添加新的必需输入 参数,则图将向受影响的客户端返回错误。
名称 | 描述 |
---|---|
REQUIRED_ARG_ADDED | 一个非可为空的参数被添加到至少被一个操作使用的字段中。 |
REQUIRED_FIELD_ADDED_TO_INPUT_OBJECT | 一个没有默认值的非空字段被添加到至少被一个操作使用的输入对象中。 |
就地更新
这些更改更新现有的架构元素。如果操作正在积极使用被更新的元素,则操作可能会从您的图接收到错误。它也可能收到意外的结果。
ⓘ 注意
在某些情况下,就地更新在运行时与受影响的客户端兼容(例如类型重命名或从对象到使用相同 字段的接口的转换)。但是,架构检查将这些更改标记为破坏性更改,因为验证没有足够的信息来确保它们的安全性。
名称 | 描述 |
---|---|
FIELD_CHANGED_TYPE | 至少被一个操作使用的现有字段更改了其类型。 |
INPUT_OBJECT_FIELD_CHANGED_TYPE | 一个现有输入字段的类型发生了变化。该字段在下另一个字段中被引用,而这个字段至少被一个操作使用。 |
TYPE_CHANGED_KIND | 至少被一个操作使用的现有类型更改了其“类型”。例如,对象类型被更改为联合类型。 |
ARG_CHANGED_TYPE | 至少一个操作使用的字段上的现有参数更改了其类型。 |
ARG_CHANGED_TYPE_OPTIONAL_TO_REQUIRED | 至少一个操作使用的字段上的现有参数从可选类型更改为必需类型。 |
默认值
这些更改更新了 参数或输入类型的默认值。如果操作正在使用您的图的元素,并且没有指定此参数的值,则当架构更新时,如果它依赖于原始的默认值,该操作可能会得到意外结果。
ⓘ 注意
您可以使用忽略条件设置来忽略默认值更改。默认值删除仍然可能是破坏性更改。
名称 | 描述 |
---|---|
ARG_DEFAULT_VALUE_CHANGE | 至少被一个操作使用的现有字段有默认值被添加、更改或删除。 |
INPUT_OBJECT_FIELD_DEFAULT_VALUE_CHANGE | 至少被一个操作使用的现有输入对象的字段默认值发生变化。 |
INPUT_OBJECT_FIELD_DEFAULT_VALUE_REMOVED | 至少被一个操作使用的现有输入对象的字段默认值被删除。 |
非破坏性更改
这些更改由架构检查检测,但它们是“安全”的。如果部署,它们绝对不会影响任何现有客户端的行为。
架构添加
名称 | 描述 |
---|---|
添加字段 | 已向现有类型中添加一个字段。 |
添加类型 | 已将一个类型添加到模式中。 |
向枚举值中添加值 | 已向枚举中添加一个值。如果客户端包含对枚举值的switch语句并且没有包含default 情况,此更改可能会导致意外的行为。 |
向联合类型中添加类型 | 已向至少由一个操作使用的联合类型中添加一个类型。 |
向接口中添加类型 | 已将接口应用于至少由一个操作使用的对象。 |
添加可选参数 | 已向现有字段添加可空参数。 |
向输入对象中添加可选字段 | 已向现有输入对象添加可选字段。 |
向输入对象字段添加默认值 | 至少由一个操作使用的现有输入对象字段已添加了默认值。 |
弃用
名称 | 描述 |
---|---|
弃用字段 | 已弃用一个现有字段。 |
移除字段弃用 | 先前已弃用的字段不再被弃用。 |
字段弃用原因更改 | 字段弃用指定的原因已更改。 |
弃用枚举 | 已弃用一个现有枚举。 |
移除枚举弃用 | 先前已弃用的枚举不再被弃用。 |
枚举弃用原因更改 | 枚举弃用指定的原因已更改。 |
描述
名称 | 描述 |
---|---|
类型描述更改 | 现有类型的描述已更改。 |
字段描述更改 | 现有字段的描述已更改。 |
枚举值描述更改 | 现有枚举值的描述已更改。 |
参数描述更改 | 现有参数的描述已更改。 |
限制
操作检查基数
操作检查将对最多10,000个不同的操作运行。当达到较大的基数时,UI将显示警告消息。
输入字段使用报告
ⓘ 注意
输入 field 使用限制适用于从 Apollo Server 和旧版本的 Apollo Router Core 报告指标。
如果您使用 GraphOS Router 报告操作指标,您可以为 增强操作签名归一化 和 扩展引用报告 配置以跟踪输入 field 使用情况。
GraphOS 跟踪操作使用情况。为了去重操作,Apollo 使用 操作签名 来非规范化 arguments 和 inputs。这意味着操作签名的结果不跟踪输入类型上使用了哪些字段。
例如,GraphOS 无法跟踪在此模式中输入字段 GetUsersInput.firstName
被使用多少次:
type Query {getUsers(filters: GetUsersInput): [User]}input GetUsersInput {firstName: StringlastName: String}type User {id: ID!firstName: String!lastName: String!}