REST集合和单个项目的缓存注意事项

时间:2011-10-27 11:39:20

标签: rest http-caching

我正在开发一个新的REST-ful API,它的主要/唯一消费者将是智能/非网络浏览器客户端。我有一个由后台进程维护/更新的集合资源,而不是客户端本身。第一次迭代所需的唯一内容类型是JSON。 URI类似于:

  • /items/ - 表示项目集合的资源。
  • /items/123 - 表示ID为123的个别项目的资源。

虽然客户端不会创建新项目,或者更新集合以添加/删除项目,但更新单个项目中的某些值。我的计划是使用HTTP PATCH来使用我自己的JSON补丁格式更新项目资源。

将会有许多并发客户端读取项目,并且不同项目的并发更新,偶尔同时更新同一项目,虽然允许一定程度的“最终一致性”,但我想将其设计为“缓存友好”尽可能的方式。读取PATCH的RFC,我看到在成功响应PATCH时,应该使用响应更新Request-URI的缓存(如果有的话)。问题归结为:

我:

A)在/items/集合资源JSON表示中包含各个项目的完整表示,并将PATCH发送到/items/ URI并包含要更新的在补丁格式?

优点:

  • 这样,客户端只需显示资源列表就可以执行N个请求数
  • 允许在客户端更新项目时使items的任何缓存失效。

CONS:

  • 这对我来说不是那么“干净”,因为我并没有真正更新这个系列,而是一个单独的项目。
  • 这会使整个集合的缓存失效,而不是更改单个项目的缓存。

B)在资源集合的JSON表示中,仅包括指向所包含项目的链接,并让客户端在发现哪些项目在集合中后请求各个项目。 HTTP PATCH将被发送到单个项目URI(例如/items/123

优点:

  • 独立缓存集合和项目资源。单个项目的PATCH可以正确地使该项目的缓存无效。
  • API更清晰,因为您要对要更新的特定项目发出HTTP PATCH。

CONS:

  • 不允许批量更新项目。这根本不是一个要求,我将来也不会预见到,但事后才知道是20-20。
  • 要求客户发出N+1次请求以显示完整的项目列表。

2 个答案:

答案 0 :(得分:2)

我会选择B.但是你的客户通常要求所有的收藏(我的意思是他们需要收集)吗?如果不是A选项会产生过多的流量。并且所有项目都会发生缓存失效(因为它们在集合中)。

如果您的客户主要获得整个集合,那么A带有特定项目的查询参数也是一种选择。

答案 1 :(得分:2)

我曾经有类似的要求,客户想知道最新更新的项目。为此,我使用'last-updated'参数增强了我的收藏资源:


GET /items?modifiedAfter=2011-10-10/10:10:10

这个modifiedAfter信息需要附加到后端某处的item-data。 Api-Clients可以自己决定他们想要抓取多少或多远。完整查询和delta查询都很容易实现。

尝试使用PATCH并对集合进行缓存非常困难并且远非微不足道(使用标准E-Tag标头,显示感兴趣的“正确”项目等,硬客户端实现)。主要问题是,集合通常具有非常动态和变化的行为。

最后在收集资源上使用modifiedAfter时,服务器端和api-client端都很高兴。

除了缓存问题,还要评估您是否真的需要部分更新。在大多数情况下,我更喜欢更简单的完整更新(使用PUT)。