概述
在某些GraphQL 操作中,某些 字段的解析时间可能比其他字段长。这可能意味着我们的用户长时间盯着加载界面,而这并不是我们希望看到的。
在本课程中,我们将
- 了解
@defer
指令 - 将
@defer
指令应用到我们的 查询中的一个慢 字段
调查慢查询
我们来用这个 操作作为示例,该 GetRecipePage
操作包含有关于具体食谱的详细信息、其成分和说明。它还会要求提供一份最近新增食谱的列表。
query GetRecipePage {recipe(id: "recOZrH0RhjSjATBp") {idnamecookingTimeprepTimereadyTimeservingsinstructionsingredients {text}}recentlyAddedRecipes {namecookingTimeservings}}
当我们尝试运行它时,我们可以亲身体验到这个查询需要花费多长时间。 🐢
从客户端应用程序的角度来看,重要信息就是食谱详细信息。这是用户想要立即看到的内容!不幸的是, recentlyAddedRecipes
字段让一切都慢了下来。 @defer
来拯救你!
@defer
指令
@defer
指令可以使我们的查询渐进地接收特定 字段的数据,而不是等到同时接收所有字段的数据。当 查询中的某些字段(如 recentlyAddedRecipes
字段及其子字段)需要更长的时间才能解析时,此指令非常有用。
我们在模式中只能延迟特定的 字段,具体包括:
- 的根 字段
Query
类型(及其子字段)。 - 域任何实体类型(及其子域)
因为recentlyAddedRecipes
是我们的Query类型中的根域,它匹配第一种情况,我们可以安全地推迟它!
注意:好奇实体类型?查看我们的 Odyssey Voyage 系列。
如何使用 @defer
要使用@defer
指令,我们将其应用于查询中的片段。探索器中有一个简单的方法可以做到这一点,所以我们不必每次都记住语法。
使用GetRecipePage
操作打开,我们将光标放在域上,我们希望推迟: recentlyAddedRecipes
。然后,右键单击并选择“用内联 @defer 片段”包裹(或“提取 @defer 片段”),探索器会自动为我们处理语法。
我们的查询现在应如下所示:
query GetRecipePage {recipe(id: "recOZrH0RhjSjATBp") {idnamecookingTimeprepTimereadyTimeservingsinstructionsingredients {text}}... @defer {recentlyAddedRecipes {namecookingTimeservings}}}
让我们现在运行查询。
我们可以看到一个名为“响应时间表”的新部分。
当我们悬停在第一个圆圈上时,我们可以看到我们的食谱数据已返回,但没有recentlyAddedRecipes
域。
当我们悬停在第二个圆圈上时,几秒后,我们可以看到返回的其他数据。
这将会对我们的客户端应用程序体验产生重大影响。
注意:客户端必须支持接收延迟查询响应,作为分批 HTTP 响应。此功能目前在Apollo Client(针对 Web 和 Kotlin,试验版)中受支持。
实践
使用以下模式来回答问题
type Query {availableFruits: [Fruit]fruit(id: ID): FruitrandomFruit: Fruit}type Mutation {buyFruit(fruitId: ID): Fruit}type Fruit {id: IDcost: FloatisInSeason: Booleancolor: String}
关键要点
-
@defer
指令允许我们的查询以增量方式接收特定字段的数据。我们在查询的片段中应用它。 - GraphOS 路由器内置对
@defer
指令的支持。
结论
就是这样:我们已经准备好接收查询并分享 AI 生成的神奇诗歌食谱的超图!
干得漂亮!我们已经学习了超图是什么以及使其发挥作用的组件:子图和路由器。我们使用现有的GraphQLAPI 创建了一个超图,现在它已在GraphOS内部设置成功。我们已经准备好让 API 消费者试用的变体。我们有权访问操作和字段度量,并按客户端分层,我们可以使用 defer 来提升我们的用户体验。
这仅仅是开始;我们已经开胃了,我希望你渴望了解更多!
如果你想学习如何安全地对超图进行更改,下一课程“GraphOS:安全的 API 交付”最适合你!我们到时候见!👋
分享你对本课程的问题和评论
你的反馈有助于我们提高!如果你遇到困难或困惑,请告诉我们,我们会帮助你。所有评论都是公开的,并且必须遵守 Apollo 行为准则。请注意,已解决或已处理的评论可能会被移除。
你需要一个 GitHub 帐户才能在下方发布。没有帐户? 改在我们的 Odyssey 论坛中发布。