使用 HTTP 管理 API 资源缓存

Managing API Resource Caching With HTTP

我目前正在使用 ASP MVC API 开发 SPA。我们最近通过 HTTP headers 在我们的 API 响应中添加了客户端缓存,并根据预期的更改频率使用适当的 max-age 值。

虽然这有助于提高性能,但我们现在遇到了用户自己进行更改然后在重新加载页面时使用旧数据命中缓存的问题。

为了解决这个问题,我在 GET 请求中添加了一个版本参数,每次进行更改时该参数都会递增。

但是,我现在发现 RFC 7234 Sec 4.4 声明 POST,PUT 或 DELETE 请求应该使相同 URI 的 GET 请求缓存无效。

鉴于此,我想知道我应该如何更好地设计我的 APIs,这样版本参数就不是必需的,浏览器会自动处理它。

例如:我有

  1. GET /resource - Returns 所有资源的 collection
  2. POST /resource - 创建新资源
  3. GET /resource/{id} - 获取指定id的资源
  4. PUT /resource/{id} - 使用指定的 id 更新资源。

请求 2 将使 1 无效,4 将使 3 无效,但是 4 也应使 1 无效。

这是正确的行为吗?或者应该只请求 1 return a collection 所有资源的 ID,我应该为每个 ID 单独请求 3s。这似乎无效,因为它会在 100 个请求而不是 1 个请求中解决。

有没有简单的解决方法?

在您引用的同一章中,规范指出:

Note that this does not guarantee that all appropriate responses are invalidated.

失效在分布式环境中是一项非常困难的任务。可能有其他缓存或依赖相同数据的其他资源(如您的情况)。这意味着不应该尝试,将它计划到系统中会更便宜。

一个"workaround"是让客户端强制更新它知道必须更改的资源,因为PUT。因此,您可以为自己(以及缓存)发出请求,以使用此 header:

更新 "parent" 资源的表示
Cache-Control: max-age=0

同样,其他缓存可能仍然有 out-of-date 但仍然有效的缓存响应,但它解决了同一台机器上同一进程不接收冲突信息的问题。

所以我不会 "normalize" return 只是没有任何数据的 URI 的表示,我宁愿以尽可能避免此类问题的方式设计工作流。如果不是,强制刷新(如所述),设置足够小的缓存时间,或者如果所有其他方法都失败则不缓存。