Apollo Kotlin中的声明性缓存ID
在启用标准化缓存 在 Apollo Kotlin 中,建议您为您的模式中的每个 对象类型指定一个 缓存ID。如果不这样做,对象将被分配一个 默认 缓存ID,但该ID可能会导致不希望的数据重复。
在指定缓存ID时,建议您使用本文中描述的方法 声明性地 执行操作:
extend type Book @typePolicy(keyFields: "id")
对于高级用例,您还可以编程方式定义缓存ID。编程方式定义。
工作原理
使用声明式缓存ID,代码生成过程会自动添加ID字段,并为任何对象生成类型安全的代码,从而返回有效的缓存ID。
为了实现这个功能,Apollo Kotlin扩展了您的后端模式。GraphQL协议支持使用对象扩展,可通过对象扩展实现这一功能。extend type
关键字。我们可以与@typePolicy
和@fieldPolicy
指令一起使用,还需要一个名为extra.graphqls
的额外.graphqls
文件。
请注意,您需要确保extra.graphqls
文件包含在您的模式配置
您可以从前两个来源之一获取特定对象类型的缓存ID:
来源 | 指令 | 描述 |
---|---|---|
从响应对象的字段获取(例如,Book.id ) | @typePolicy | 这发生在网络请求之后,对于合并查询结果与现有缓存数据至关重要。这是最常见的情况。 |
来自GraphQL操作的参数(例如,author(id: "au456") ) | @fieldPolicy | 这发生在网络请求之前,可以让你避免在网络请求中如果所有请求数据已经在缓存中。这是一个可选的优化,可以避免一些缓存未命中。 |
@typePolicy
的@typePolicy
指令 使您能够指定从您的GraphQL服务器 返回的对象的 键字段 中指定的对象缓存ID。
例如,假设我们的应用schema.graphqls
文件中包含以下定义:
type Book {id: String!author: Author!title: String!}
我们可以在与我们的模式相同的目录中一个名为 extra.graphqls
的文件中添加以下定义:
extend type Book @typePolicy(keyFields: "id")
Apollo Kotlin现在知道要使用 id
字段 生成 Book
类型 的缓存ID。
对于对象,您可以指定多个键字段 如果它们都是唯一识别特定缓存条目的必需字段:
extend type Author @typePolicy(keyFields: "firstName lastName")
在这种情况下,Author
对象的缓存ID包括其 firstName
和 lastName
字段 的值。
@fieldPolicy
的@fieldPolicy
指令 允许您指定一个对象的缓存ID,这是您提供给某个特定字段的 键参数 的值。这使您能够在发送网络请求之前在您的缓存中标识对象,可能使您能够完全跳过请求。
例如,假设我们的应用schema.graphqls
文件中包含以下定义:
type Query {book(id: String!): Book}
我们知道这个查询 返回具有所需 id
字段的任何 Book
对象。因此,我们可以将 id
参数作为此字段的键参数。
我们可以在与我们的模式相同的目录中一个名为 extra.graphqls
的文件中添加以下定义:
extend type Query @fieldPolicy(forField: "book", keyArgs: "id")
Apollo Kotlin现在知道在发送对 Query.book
的网络请求之前,在缓存中检查具有提供的 id
的 Book
对象。
请注意,虽然@fieldPolicy
指示符对应一个单独的字段,但您需要将该指示符应用于 类型 定义(在本例中为 Query
)。这是因为 GraphQL 不允许扩展单个字段。您可以使用 forField
参数来指定指示符所对应的字段。
如果一个字段的多个键参数都必须用于唯一标识特定的缓存条目,您可以为该字段指定多个键参数:
extend type Query @fieldPolicy(forField: "author", keyArgs: "firstName lastName")
在本例中,Author
对象的缓存 ID 包含其 firstName
和 lastName
字段值,这些值都作为参数传递到 Query.author
字段。
如果一个对象类型的多个字段具有键参数,您可以为此类型应用多个 @fieldPolicy
指示符。