6. 字段弃用
5m

🗑️ 替换模式中的字段

这对于一个不断发展来说是一个非常常见的场景,即为了支持新的字段而弃用现有的模式字段。让我们看看如何在 Catstronauts 模式中完成这项工作。

正如我们在进行一些代码清理工作时发现,lengthTrackModule被文档化为以分钟为单位。然而,在经过一番挖掘后,我们发现这是不正确的,我们从 REST API 返回的值实际上是以为单位的!客户端应用程序正在做这项工作以将这个数字转换为分钟。

我们应该在模式中修复描述,以便未来的客户端不会受到误导。我们还可以改进我们的模式,使其更明确地说明这个的确切含义。

这需要进行模式变更!以下是计划:

  1. 向模式中添加一个新的
  2. 将旧的标记为弃用。
  3. 监控旧的使用情况。
  4. 每当使用率下降并且客户端有足够的时间做出相应的更改时,我们就可以安全地删除旧的

让我们开始吧!

添加新字段

首先,我们将向我们的模式中添加一个新的。打开server存储库。

"The track's full duration, in seconds"
durationInSeconds: Int

"The module's video duration, in seconds"
durationInSeconds: Int

✍️ 添加解析器

const resolvers = {
Query: {
/* query resolvers */
},
Mutation: {
/* mutation resolvers */
},
Track: {
/* Track.author and Track.modules resolvers */
durationInSeconds: () => {},
},
};

durationInSeconds 期间,我们将对第一个参数的 length 属性进行解构。我们不需要其他任何 解析器参数,并立即在该 resolver 的主体中返回那个 length 值。

durationInSeconds: ({ length }) => length,

我们还会以同样的方式处理 Module.durationInSeconds 的解析器。在 resolvers.js 文件中 resolvers 对象内,让我们为 Module 创建一个新的对象,并添加 durationInSeconds resolver

server/src/resolvers.js
Module: {
durationInSeconds: ({ length }) => length,
},
如果我们的GraphQL服务器只使用REST API作为其唯一的数据源,以下哪个说法是正确的?

这就完成了我们的新 。接下来,我们需要将 length field 标记为已弃用。

↔️ 模式指令

为了将一个 标记为已弃用,我们将使用 模式的 。模式指令以 @ 字符表示,并装饰了您的模式中的一个特定符号,例如一个类型或 定义。

Illustration showing the syntax for a directive in a schema

我们的服务器(或任何与其他模式交互的系统)可以根据其 执行针对该符号的自定义逻辑。对于我们的用例,我们将使用 's 的默认指令之一: @deprecated

Illustration showing the syntax for the deprecated directive in a schema

我们使用 @deprecated 指令来标记一个 ,表示此字段已被弃用!我们应始终向此指令传递一个 reason ,说明为何弃用,并指出客户端应该使用哪个 。这对于客户端查询你的 信息很有用。

Illustration showing the syntax for using the deprecated directive in the schema with the reason argument
模式指令
模式指令以 `字符开头,它可以在模式中的特定符号之后出现,例如
 
`
 
`
 
。一个默认指令的示例是
 
`
 
,它表示字段不应再被使用。此指令经常与 ` 参数一起使用,以指定为何字段不应使用,或者应使用哪个字段。

将此框中的项拖到上面的空白处

  • reason

  • fields

  • @

  • @deprecated

  • @deleted

  • resolvers

  • types

  • description

  • !

  • message

🗑️使用 @deprecated 指令

再次打开 schema.js 文件。在 Track 类型中,在 length 的返回类型之后,我们将添加 @deprecated 指令,并将 reason 设置为 "Use durationInSeconds"。我们还将更新描述,将其改为 "in seconds"(而不是 "in minutes",这是不正确的)。

现在,Track.length 应该看起来像这样:

server/src/schema.js
"The track's approximate length to complete, in seconds"
length: Int @deprecated(reason: "Use durationInSeconds")

让我们将相同的更新应用到 Module.length

server/src/schema.js
"The module's length in seconds"
length: Int @deprecated(reason: "Use durationInSeconds")

就这样,我们已经完成了服务器端的最后一次更改!

如果你在本地项目上进行编码,确保在继续之前测试你的 API 变更,以确认你可以 两者(track 和 module)上的新 durationInSeconds

代码挑战!

让我们进行一些数据库模式更改!我们将用completedMissionsCount替换Spaceship的missionCount字段。废弃missionCount字段,并为use completedMissionsCount提供一个reason参数。为completedMissionsCount添加一个新的字段,它是一个可为空的Int。为此字段编写一个有用的描述,重复使用missionCount的描述。

在我们确认本地一切正常之后,我们就可以将我们的更改推送到生产环境了。你们都知道步骤了:添加并提交我们的更改,将其推送到GitHub,并等待Railway部署我们的服务器应用程序的最新版本。

任务!

设置完成!

上一个

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

您的反馈有助于我们改进!如果您遇到了困难或感到困惑,请告诉我们,我们会帮助您。所有评论都是公开的,必须遵守 Apollo行为准则。请注意,已解决或处理的评论可能被删除。

您需要GitHub账户才能在下方发布。还没有吗? 请在我们的大 Molis论坛上发表帖子。