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

自定义缓存键


当与规范化缓存协同工作时,建议你为每个缓存 ID指定一个

规范化缓存为存储在缓存中的每个对象计算一个缓存键。使用,你可以自定义缓存键的计算,以改进缓存的性能和功能。

有关更多信息,请参阅缓存如何通过缓存键规范化对象

CacheKeyInfo

构造缓存键所需的信息由一个CacheKeyInfo值表示。这个struct包括两个属性,你可以提供它们以影响缓存键的计算方式:

  1. let uniqueKeyGroup: String?

    一组应在规范化缓存中一起组合的对象的可选分组标识符。这是缓存键的第一个组件。

    重要:缓存键组的唯一性

    具有相同uniqueKeyGroup的所有对象必须在所有类型中具有唯一的id

    为了避免缓存键冲突,缓存键将始终包含一个组标识符组件。当uniqueKeyGroupnil(默认值)时,响应对象中的__typename用作组标识符的默认值。

    如果缓存中将可以合并多个不同类型的对象,则每个ObjectCacheKeyInfo应该具有相同的uniqueKeyGroup

    提示:通过将对象分组,它们在规范化缓存中的将具有相同的前缀。这允许您通过缓存的id搜索同一组中的缓存对象。要了解更多信息,请阅读有关直接缓存访问

  2. let id: String

    代表对象的唯一缓存 ID。它用作缓存键的第二部分。

    重要:

    ID必须对所有具有相同组标识符__typenameuniqueKeyGroup)的对象是确定性的且唯一的。

    也就是说,对于代表缓存中同一的响应对象,其键将会是相同的;并且对于代表具有相同组标识符的其他不同对象,也不会使用相同的键。

规范化缓存构建缓存键的格式

"${GroupIdentifier}:${CacheID}"

给定一个CacheKeyInfo

CacheKeyInfo(id: "123", uniqueKeyGroup: "Animal")

Apollo iOS会构建一个形如"Animal:123"的缓存键。

SchemaConfiguration 文件

The SchemaConfiguration 文件是您配置模式中类型缓存键的起点。

Apollo iOS 为您的项目生成代码时,它会生成一组代表应用 GraphQL 语法的元数据类型。SchemaConfiguration.swift

如果代码生成引擎检测到该文件不存在,则会创建此文件,但永远不会覆盖现有的 SchemaConfiguration.swift文件。这意味着您可以在后续代码生成运行中不会覆盖方案配置的情况下编辑您的方案配置。

提示:您可以在代码生成配置中通过 output.schemaTypes 选项来配置生成的方案类型的位置。

指定缓存 ID

`SchemaConfiguration` 包含一个 cacheKeyInfo(for:type:object:) 函数。此函数为您提供 JSON 响应object 和所表示对象的具体 type

`object` 参数提供来自网络请求或缓存命中的 JSON 响应。

`type` 参数提供了一个强类型 Object 类型。这是一个表示 GraphQL 方案中具体 type 的生成元数据类型。

要配置如何从响应对象中计算缓存键,您可以创建并从您的 cacheKeyInfo(for:object:) 实现

注意:在指定缓存ID时,请确保您总是获取用于构建这些ID的来执行您的操作。任何不包含缓存ID 字段的响应对象将无法通过缓存归一化进行合并。

使用默认缓存ID字段

如果您的架构在许多对象类型之间提供了常见的唯一标识符,您可能希望将该作为默认的缓存ID使用。

SchemaConfiguration.swift
public enum SchemaConfiguration: ApolloAPI.SchemaConfiguration {
static func cacheKeyInfo(for type: Object, object: ObjectData) -> CacheKeyInfo? {
guard let id = object["id"] as? String else {
return nil
}
return CacheKeyInfo(id: id)
}
}

如果JSON响应对象没有id字段,函数返回nil,且缓存将使用默认的响应路径归一化来归一化对象。

JSON值便利初始化器

或者,您可以使用init(jsonValue:uniqueKeyGroup:)便利初始化器。此初始化器尝试使用JSON响应中某个键的值,如果该键不存在则抛出错误。

如果您希望在值不存在时返回nil,则可以使用try?

SchemaConfiguration.swift
public enum SchemaConfiguration: ApolloAPI.SchemaConfiguration {
static func cacheKeyInfo(for type: Object, object: ObjectData) -> CacheKeyInfo? {
return try? CacheKeyInfo(jsonValue: object["id"])
}
}

Object类型指定缓存ID

如果您希望为不同类型的对象指定不同的缓存ID,则可以使用type参数。

例如,对于具有唯一键字段idDog类型对象,您可能可以实现缓存键解析如下:

SchemaConfiguration.swift
public enum SchemaConfiguration: ApolloAPI.SchemaConfiguration {
static func cacheKeyInfo(for type: Object, object: ObjectData) -> CacheKeyInfo? {
switch type {
case Objects.Dog:
return try? CacheKeyInfo(jsonValue: object["id"])
default:
return nil
}
}
}

按抽象类型指定缓存ID

如果架构中具有相同interfaceunion的对象类型共享相同的缓存键解析策略,则您可以根据这些抽象类型解析键。

生成的架构元数据包括InterfacesUnions类型,其中包含在您的GraphQL架构中使用的所有抽象类型列表。

例如,对于实现interface PetDogCat类型架构,您可能可以实现缓存键解析如下:

SchemaConfiguration.swift
public enum SchemaConfiguration: ApolloAPI.SchemaConfiguration {
static func cacheKeyInfo(for type: Object, object: ObjectData) -> CacheKeyInfo? {
if type.implements(Interfaces.Pet) {
return try? CacheKeyInfo(jsonValue: object["id"])
}
return nil
}
}

要配置基于联合(union)类型的缓存键解析,请使用联合的possibleTypes属性。

SchemaConfiguration.swift
public enum SchemaConfiguration: ApolloAPI.SchemaConfiguration {
static func cacheKeyInfo(for type: Object, object: ObjectData) -> CacheKeyInfo? {
if Unions.ClassroomPets.possibleTypes.contains(type) {
return try? CacheKeyInfo(jsonValue: object["id"])
}
return nil
}
}

使用uniqueKeyGroup分组合并缓存对象

如果您的缓存ID在整个不同的类型中保证是唯一的,您可能希望在缓存中使用一个共同的uniqueKeyGroup把它们分组在一起。

有关合并缓存对象的更多信息,请参见uniqueKeyGroup

例如,如果所有实现interface Animal的对象(无论是DogCat还是其他实现了Animal的类型)都有唯一的缓存ID,它们可以共享一个uniqueKeyGroup

SchemaConfiguration.swift
public enum SchemaConfiguration: ApolloAPI.SchemaConfiguration {
static func cacheKeyInfo(for type: Object, object: ObjectData) -> CacheKeyInfo? {
if type.implements(Interfaces.Pet) {
return try? CacheKeyInfo(
jsonValue: object["id"],
uniqueKeyGroupId: Interfaces.Pet.name
)
}
return nil
}
}

注意事项与限制

在实现缓存键解析函数时,请注意缓存键解析有几点显著的异常和限制。

  1. 虽然对象的缓存键可以使用另一个嵌套对象的字段,但如果在另一个中更改了引用对象的字段,则依赖于该对象的缓存键将不会更新。对于没有与自己的缓存键进行归一化的嵌套对象,这不会发生,但如果嵌套对象是具有自己缓存键的实体,它可以独立地进行变异。在这种情况下,任何缓存键依赖于被变异实体的其他对象都不会自动更新。您必须注意使用缓存手动更新这些实体。

  2. 此函数传递给此函数的object表示特定模型中对象的数据,而不是模式中的类型。这意味着别名字段将按它们的名称进行键控,而不是模式类型上的字段名称。

  3. 此函数的object参数是一个ObjectData结构,它包装了底层对象数据。由于缓存键解析在原始JSON(来自网络响应)上以及SelectionSet模型数据(直接写入缓存时)上都会执行,底层数据将具有不同的格式。ObjectData包装器用于在此上下文中将此数据归一化到一致格式。

上一页
直接缓存访问
下一页
创建客户端
评级文章评级在GitHub上编辑编辑论坛Discord

©2024Apollo Graph Inc.,商业名称:Apollo GraphQL。

隐私政策

公司