概览
我们从打算对超图.
在本课中,我们将
- 学习在我们的架构中替换 字段 的过程
- 了解 GraphQL 指令 的用途
- 使用
@deprecated
指令 在我们架构中的 字段 中
迄今为止的架构
一个日益发展的 图 的常见情况是在架构中弃用现有 字段,转而采用新字段。我们将在 Poetic Plates 超图 中调查一个这样的情况
以下展示 Ingredient
类型的架构:
type Ingredient {id: ID!"Display text for the ingredient"text: String"The name of an ingredient"name: String"A potential substitute for the ingredient, if available"substitute: String}
用户反馈表示,对于 text
和 name
字段,他们产生了混淆。
我们来看看这些 字段 返回哪些值。使用 超图 的 Explorer,运行以下 查询,以检索随机食谱的成分列表。
query GetRandomRecipeIngredients {randomRecipe {ingredients {textname}}}
根据你随机收到的食谱,你的响应可能有所不同,但以下是对我们接收到的内容的摘录
{"data": {"randomRecipe": {"ingredients": [{ "text": "1 cup onions, medium diced", "name": "onions" },{ "text": "2 tbsp olive oil", "name": "olive oil" }// ...]}}}
你看到 text
和 name
之间的区别了吗?
它看起来像 text
字段 返回有关成分的更长更详细的版本。 name
字段 仅返回成分是什么,没有任何其他详细信息,如数量或如何准备。
深入研究架构中每个 字段 的说明,文档中并没有明确说明这是用户应该预期的。因此我们可以理解用户在使用这些字段时存在的困惑。
我们应该修复架构中的描述,以便更清楚地说明每个字段预期会返回什么。我们还可以改进架构,更明确地说明text
字段返回什么。也许存在一个更好的此字段的名称
此操作需要对我们的架构进行更改,但我们不希望删除text
字段,并一次性将其替换为新的字段。这样做将中断现有查询客户端正在发送的内容,我们不想让任何人担心
以下是计划
- 将新字段添加到架构中。
- 将旧字段标记为已弃用。
- 监视旧字段的使用情况
- 只要使用率下降,并且客户端有足够的时间进行更改,就可以安全地移除旧字段!
让我们开始吧
向架构中添加新字段
首先,让我们将新字段添加到架构中。
在代码编辑器中打开配方子图资料库,并导航到
schema.graphql
文件。找出
Ingredient
类型,并添加一个新的 字段,称为detailedDescription
。这个 字段 名称 非常 清晰,远胜于text
!它返回一个String
类型,我们还可以为其赋予一个准确的描述,辅以一个示例。schema.graphql"""A detailed description of the ingredient needed in the recipe.Usually in the format of: <QUANTITY> <INGREDIENT NAME>, <SPECIAL INSTRUCTIONS>.For example: 1 cup onions, medium diced"""detailedDescription: String
添加新的解析器
我们将需要一个 解析器 用于这个新的 字段。我们的 数据源 并未提供此 detailedDescription
属性。没关系,它无需与我们的架构的 字段 一一匹配。这就是 GraphQL 的妙处!
打开
src/resolvers/Ingredient.js
文件。在
Ingredient
对象下添加一个新属性,其名称与 字段 相同,即detailedDescription
。它将设置到我们的 解析器 函数中。src/resolvers/Ingredient.jsmodule.exports = {Ingredient: {detailedDescription: () => {},},};请记住,此 字段 的值将与
text
字段 的值完全相同。因此,我们需要获取该text
值并从detailedDescription
解析器 中返回该值。我们可以使用
text
值来访问 resolver 的第一个参数,parent
,这是由于 resolver 链。在
detailedDescription
resolver 中,我们将解构第一个参数(parent
)以获取text
属性。我们不需要任何其他 resolver 参数,并将直接在 resolver 主体中返回该text
值。src/resolvers/Ingredient.jsdetailedDescription: ({ text }) => text,这是我们照顾好的新 field!
测试我们的更改
让我们确保新架构添加工作正常。
如果您的服务器未运行,您可以使用npm run dev
启动它。这将在https://127.0.0.1:4001启动服务器。让我们在浏览器中访问那里,使用 Sandbox 来测试查询。
我们应该看到新的字段 detailedDescription
显示在左侧的文档面板上。
让我们尝试这个 查询检索一个随机菜谱及其成分: text
和 detailedDescription
字段。
query GetRandomRecipeIngredients {randomRecipe {ingredients {textdetailedDescription}}}
当我们获取数据后,我们应该看到 text
和 detailedDescription
字段 的值相同。
一切都按预期进行!接下来,我们需要将 text
字段标记为已弃用。
@deprecated
指令
对于我们的用例,我们将使用 GraphQL 的一个默认 指令: @deprecated
。
我们对 @deprecated
指令应用于 field,以表明该 field已...弃用!我们应该始终将 reason
参数传递给该指令,其中说明了弃用原因以及客户端应该改用哪个 field。这是对 查询你的 图的客户端的有用的信息。
使用 @deprecated
指令
再次打开
schema.graphql
文件。找到
Ingredient
类型中的text
field。在text
field的返回类型后,我们将添加@deprecated
指令,其中reason
为"Use detailedDescription"
。Ingredient.text
field现在应该如下所示:schema.graphql"Display text for the ingredient"text: String @deprecated(reason: "Use detailedDescription")
然后我们就完成了!
测试我们的更改
那么发生了什么变化?让我们找出来!你的服务器应该仍在运行并获取最新更改(如果不是,请确保再次运行 npm run dev
)。返回 https://127.0.0.1:4001。
查看我们之前相同的 query,你现在可以看到几个更改!
首先,text
字段显示带下划线的黄色波浪线,如果将鼠标悬停在其上,我们将看到原因!该字段已弃用,就像我们在模式中标记的那样。我们还可以在左侧的文档面板上看到相同的消息。
我们仍然可以毫无问题地运行查询,但该警告旨在让我们知道我们真的不应该在我们的查询中再包含text
字段
练习
将此框中的项目拖动到上方的空白处
原因
解析器
字段
@deleted
说明
类型
!
@deprecated
消息
@
关键要点
- 要替换字段在我们的模式中,我们应该:
- 添加新的字段
- 将旧的字段标记为已弃用
- 监视旧字段的使用情况
- 只要使用率下降,并且客户端有足够的时间进行更改,就可以安全地移除旧字段!
- 架构指令是用
@
字符表示的,它装饰架构中特定的符号,例如类型或字段定义。 - 要弃用字段,我们使用了默认的GraphQL 指令
@deprecated
和reason
参数以让我们的图形类使用者知道原因和哪个字段应该在替代方案中使用。 - 我们依然可以使用被弃用的字段运行查询,但是弃用状态是提示我们要停止在现有查询中使用该字段的信号。
下一步
我们已经完成了此计划的前两个步骤,但这都是在我们的本地环境中进行的。我们需要让GraphOS了解这些更改!
在接下来的两节课中,我们将了解如何使用架构检查和发布安全、自信地落地这些更改。
分享你对本课程的疑问和评论
本课程目前处于
你需要一个 GitHub 帐户才能在下面发帖。还没有吗? 转而在我们的 Odyssey 论坛中发帖。