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

Apollo Kotlin 中声明式缓存 ID


当使用

在指定缓存 ID 时,建议您使用本文中描述的方法声明式地进行。

extend type Book @typePolicy(keyFields: "id")

对于高级用例,您也可以编程式地定义缓存 ID。

它们是如何工作的

使用声明式缓存ID,代码生成过程会自动添加字段并生成可以返回任何有效缓存ID的类型安全代码。

为此,Apollo Kotlin 扩展了您的后端模式。GraphQL 规范支持对象扩展,使用extend type关键字。我们可以结合使用@typePolicy@fieldPolicy指令,以及一个命名为extra.graphqls的额外.graphqls文件。

请注意extra.graphqls文件需要包含在你的模式配置<风格=“css assets-earthmark atom<<( https://apollo.graphql.net.cn/docs/kotlin/advanced/plugin-configuration#combining-multiple-schema-files?referrer=docs-content_START )中。

从以下两个来源之一,您可以获取给定对象类型的缓存ID:

来源指令描述
从响应对象的字段中(例如,Book.id@typePolicy这发生在网络请求之后,对于将查询结果与现有缓存数据合并至关重要。这最常见。
从字段的参数中(例如,author(id: "au456")@fieldPolicy这发生在网络请求之前,可以在已缓存所有请求数据的情况下避免网络往返。这是一种可选的优化,可以避免一些缓存不命中。

@typePolicy

@typePolicy 指令允许您从一个对象的返回结果中指定的 key fields 来指定对象的缓存ID,这是您的 GraphQL 服务器所返回的。最常见的做法是使用对象的 id 域作为它的 key field。

例如,假设我们的schema.graphqls文件包括以下定义:

schema.graphqls
type Book {
id: String!
author: Author!
title: String!
}

我们可以在与我们的模式相同的目录中的 extra.graphqls 文件中添加以下定义:

extra.graphqls
extend type Book @typePolicy(keyFields: "id")

Apollo Kotlin现在知道如何使用Book类型的id字段来生成其缓存的ID。一个缓存记录现在可能看起来像这样:

"Book:bk123": {"id": "bk123", "title": "Les guerriers du silence", "author": "ApolloCacheReference{favoriteBook.author}"}

如果您需要通过多个键字段来唯一识别特定的缓存条目,则可以为对象指定多个字段:

extra.graphqls
extend type Author @typePolicy(keyFields: "firstName lastName")

在这种情况下,Author对象的缓存ID包含了其firstNamelastName字段的值:

"Author:PierreBordage": {"id": "au456", "firstName": "Pierre", "lastName": "Bordage"}

一个对象类型的所有键字段必须返回标量类型

请注意,以这种方式指定的键字段将在代码生成期间自动添加到对象类型的选取中,因为它们总是需要用来在缓存中识别对象。这意味着您不需要在查询中包含它们。

__typename添加到您的操作中

除了键字段外,声明性缓存默认情况下还要求每个对象具有其__typename。这些类型名称默认情况下不包括在内,因为它们会使非缓存用户查询更大。为了避免缓存未命中,请将__typename添加到每个使用addTypename的选取中:

apollo {
service("service") {
addTypename.set("always")
}
}

@fieldPolicy

通过@fieldPolicy指令,您可以根据您为特定字段提供的键参数值来指定对象的缓存ID。这使得您在发送网络请求之前就可以在缓存中识别一个对象,有可能完全跳过请求。

例如,假设我们的schema.graphqls文件包括以下定义:

schema.graphqls
type Query {
book(id: String!): Book
}

我们碰巧知道这个 查询 找回任何一个 Book 对象,它有一个与所需 匹配的 id 字段。因此,我们可以将该 id 参数作为此 字段 的一个关键字段。

我们可以在与我们的模式相同的目录中的 extra.graphqls 文件中添加以下定义:

extra.graphqls
extend type Query @fieldPolicy(forField: "book", keyArgs: "id")

Apollo Kotlin 现在知道在向 Query.book 发送网络请求之前,先要检查缓存以获取具有所提供 id Book 对象。.

请注意,尽管 @fieldPolicy 指令对应单个 字段,但是您将指令应用到 类型 定义(在这个例子中是 Query)。这是因为 GraphQL 不允许扩展单个 字段。您使用 forField 参数来指定指令对应的 字段。

如果您想要指定多个关键字段参数以唯一标识某个缓存条目,您可以为字段指定 多个 关键

extra.graphqls
extend type Query @fieldPolicy(forField: "author", keyArgs: "firstName lastName")

在这种情况下,Author 对象的缓存 ID 包含其 firstNamelastName 字段值的组合,这两个字段都作为 Query.author 字段的 参数 提供。

如果一个对象类型有多个字段具有关键字段参数,您可以为该类型应用多个 @fieldPolicy 指令。

上一页
标准化缓存
下一页
程序化缓存 ID
评分文章评分在GitHub上编辑编辑论坛Discord

©2024Apollo Graph Inc.,permissions Apollo GraphQL.

隐私策略

公司