如何使用结构化模型层在 Siesta 中实现持久缓存
How to implement a Persistent Cache in Siesta with a structured model layer
我正在使用(并且喜欢)Siesta 与我的 Swift 应用程序中的 REST Web 服务进行通信。我已经实现了一系列 ResponseTransformer 以将 API 调用响应映射到模型 类,以便 Siesta 资源自动解析为对象实例。这一切都很好。
我现在想实现一个 Siesta PersistantCache 对象以支持离线模式,方法是让 Siesta 通过将这些对象存储在 Realm 中将它们缓存到磁盘(而不是内存中)。我不确定该怎么做,因为文档说(关于 EntityCache.writeEntity 函数):
This method can — and should — examine the entity’s content and/or headers and ignore it if it is not encodable. While they can apply type-based rules, however, cache implementations should not apply resource-based or url-based rules; use Resource.configure(...)
to select which resources are cached and by whom.
为了符合这一准则,我已经根据 URL 服务配置期间的模式匹配为每个资源类型创建了一个特定的 PersistentCache 对象:
class _GFSFAPI: Service {
private init() {
configure("/Challenge/*") { [=10=].config.persistentCache = SiestaRealmChallengeCache() }
}
但是,由于 EntityCache 协议方法只包括对实体的引用(它公开原始内容而不是类型化对象),我看不出在调用 EntityCache.writeEntity 或如何在 EntityCache.readEntity 期间将对象拉出 Realm。
如有任何关于如何解决此问题的建议,我们将不胜感激。
问得好。每个模型都有一个单独的 EntityCache
实现当然可以,尽管创建所有这些小胶水似乎很麻烦 类.
缓存中的模型
你的 writeEntity()
被调用,无论在你所有的响应转换器的 end 出现什么。如果您的转换器配置为吐出模型 类,那么 writeEntity()
会看到模型。如果这些模型是 Realm 友好的模型,那么,我看不出有任何理由不能调用 realm.add(entity.content)
。 (如果这给您带来问题,请通过问题的更新告诉我。)
相反,当从缓存中读取时,readEntity()
returns 不会再次通过转换器管道,因此它应该 return 与您的转换器完全相同出品,即型号。
缓存查找键
您从文档中引用的特定段落写得不好,可能有点误导。当它说你“不应该应用基于资源或基于 url 的规则”时,它实际上只是试图劝阻你解析 forKey:
参数——秘密地只是一个 URL,但对缓存实现应该保持不透明。但是,您可以从给定实体收集的任何信息都是公平的游戏,包括 entity.content
.
的类型
当前 API 下的一个问题 - 这是一个严重的问题 - 是您需要保持从 Siesta 的键(您应该将其视为不透明)到不同类型的 Realm 对象的映射。您可以通过以下方式执行此操作:
- 保持专用于保持从 Siesta 缓存键到各种类型的 Realm 对象的多态映射的 Realm 模型,
- 通过添加
siestaKey
属性并进行某种跨模型联合查询,或者
- 通过在 Realm 之外保留(缓存键)→(模型类型,模型 ID)映射。
我可能会按照这个顺序追求这些选项,但我相信你在这里使用 Realm 作为 EntityCache
的支持,处于相对未开发(尽管完全合理)的领域。一旦您确定了选项,我鼓励您提交一个 Github 问题以获取任何建议的 API 改进。
我正在使用(并且喜欢)Siesta 与我的 Swift 应用程序中的 REST Web 服务进行通信。我已经实现了一系列 ResponseTransformer 以将 API 调用响应映射到模型 类,以便 Siesta 资源自动解析为对象实例。这一切都很好。
我现在想实现一个 Siesta PersistantCache 对象以支持离线模式,方法是让 Siesta 通过将这些对象存储在 Realm 中将它们缓存到磁盘(而不是内存中)。我不确定该怎么做,因为文档说(关于 EntityCache.writeEntity 函数):
This method can — and should — examine the entity’s content and/or headers and ignore it if it is not encodable. While they can apply type-based rules, however, cache implementations should not apply resource-based or url-based rules; use
Resource.configure(...)
to select which resources are cached and by whom.
为了符合这一准则,我已经根据 URL 服务配置期间的模式匹配为每个资源类型创建了一个特定的 PersistentCache 对象:
class _GFSFAPI: Service {
private init() {
configure("/Challenge/*") { [=10=].config.persistentCache = SiestaRealmChallengeCache() }
}
但是,由于 EntityCache 协议方法只包括对实体的引用(它公开原始内容而不是类型化对象),我看不出在调用 EntityCache.writeEntity 或如何在 EntityCache.readEntity 期间将对象拉出 Realm。
如有任何关于如何解决此问题的建议,我们将不胜感激。
问得好。每个模型都有一个单独的 EntityCache
实现当然可以,尽管创建所有这些小胶水似乎很麻烦 类.
缓存中的模型
你的 writeEntity()
被调用,无论在你所有的响应转换器的 end 出现什么。如果您的转换器配置为吐出模型 类,那么 writeEntity()
会看到模型。如果这些模型是 Realm 友好的模型,那么,我看不出有任何理由不能调用 realm.add(entity.content)
。 (如果这给您带来问题,请通过问题的更新告诉我。)
相反,当从缓存中读取时,readEntity()
returns 不会再次通过转换器管道,因此它应该 return 与您的转换器完全相同出品,即型号。
缓存查找键
您从文档中引用的特定段落写得不好,可能有点误导。当它说你“不应该应用基于资源或基于 url 的规则”时,它实际上只是试图劝阻你解析 forKey:
参数——秘密地只是一个 URL,但对缓存实现应该保持不透明。但是,您可以从给定实体收集的任何信息都是公平的游戏,包括 entity.content
.
当前 API 下的一个问题 - 这是一个严重的问题 - 是您需要保持从 Siesta 的键(您应该将其视为不透明)到不同类型的 Realm 对象的映射。您可以通过以下方式执行此操作:
- 保持专用于保持从 Siesta 缓存键到各种类型的 Realm 对象的多态映射的 Realm 模型,
- 通过添加
siestaKey
属性并进行某种跨模型联合查询,或者 - 通过在 Realm 之外保留(缓存键)→(模型类型,模型 ID)映射。
我可能会按照这个顺序追求这些选项,但我相信你在这里使用 Realm 作为 EntityCache
的支持,处于相对未开发(尽管完全合理)的领域。一旦您确定了选项,我鼓励您提交一个 Github 问题以获取任何建议的 API 改进。