加入我们,于10月8日至10日在纽约市了解最新的GraphQL Federation和API平台工程技巧、趋势和新闻。加入2024年纽约市的GraphQL峰会
文档
免费开始

在 Apollo 客户端中使用 @defer 指令

增量接收查询响应数据


Apollo 客户端中的 @defer 指令目前处于 通用可用性阶段,并由安装 @apollo/client@latest 提供。如果您对此有任何反馈,请通过GitHub 问题

从版本3.7.0开始支持对@defer指令的预览支持。这个指令允许您的查询接收对特定逐步数据的获取,而不是一次性得到所有字段数据。这对于查询中的一些字段需要比其他字段花费更长的时间进行解析时非常有用。

为了成功地将字段延迟处理,被查询的端点必须支持@defer指令。基础的@defer支持在GraphOS Router中已进入通用可用阶段,并且与所有联邦兼容的子图库兼容。

示例

假设我们正在构建一个社交媒体应用程序,它可以快速获取用户的个人资料信息,但获取该用户的友友信息需要较长时间。

GraphQL允许我们在单个查询中声明UI所需的全部字段,但这也意味着我们的查询的响应速度将与解析速度最慢的字段一样慢。使用@defer指令允许我们标记查询中对于应用程序初始渲染不是必要的部分,这将一旦可用就被解析。

为了实现这一点@defer指令到包含所有与数据相关的慢解析字段中:

query PersonQuery($personId: ID!) {
person(id: $personId) {
# Basic fields (fast)
id
firstName
lastName
# Friend fields (slower)
... @defer {
friends {
id
}
}
}
}

使用这种语法,如果查询服务器支持 @defer,我们的客户端可以首先在初始响应负载中接收“基本字段”,然后是包含“朋友字段”的附加负载。

让我们以React为例。这里我们可以假设GET_PERSON是上述查询,即PersonQuery,带有延迟的朋友id列表:

app.jsx
import { gql, useQuery } from "@apollo/client";
function App() {
const { loading, error, data } = useQuery(GET_PERSON, {
variables: {
id: 1,
},
});
if (loading) return "Loading...";
if (error) return `Error! ${error.message}`;
return (
<>
Welcome, {data.firstName} {data.lastName}!
<details>
<summary>Friends list</summary>
{data.friends ? (
<ul>
{data.friends.map((id) => (
<li>{id}</li>
))}
</ul>
) : null}
</details>
</>
);
}

当后续的延迟数据块到达时,useQuery将重新渲染(由于延迟的多部分响应之间的重新渲染,loading保持为false)并且当它们到达时,data将包含延迟数据。

因此,@defer可以被视为一种工具,用于提高初始渲染速度,因为一些较慢的数据将在页面底部或屏幕外显示。在这种情况下,我们在默认关闭的<details>元素内部渲染朋友列表,避免了当friends数据到达时的布局偏移。

使用与代码生成

如果您目前正在使用 GraphQL Code Generator 来满足您的代码生成需求,您需要使用 4.0.0 或更高版本的 Codegen。请参阅 Codegen 文档 以获取更多信息。

在 React Native 中的使用

为了在 React Native 应用中使用 @defer,需要配置额外的设定。请参阅 React Native 文档 以获取更多信息。

下一步
简介
评分文章评分在 GitHub 上编辑编辑论坛Discord

©2024阿波罗图公司,简称阿波罗GraphQL。

隐私政策

公司