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

发布于 2024-12-12 05:13:39 字数 1372 浏览 1 评论 0原文

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

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

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

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

我是否:

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

优点

  • 这使得客户端不必仅仅为了显示资源列表而执行 N 次请求,
  • 从而使任何 items 缓存失效当客户更新项目时。

缺点:

  • 这对我来说并不“干净”,因为我并不是真正更新集合,而是更新单个项目。
  • 这会使整个集合的缓存无效,而不是更改的单个项目的缓存。

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

优点:

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

缺点:

  • 不允许批量更新项目。目前这根本不是一个要求,我也没有预见到将来会出现这种情况,但只是事后看来是20-20。
  • 要求客户端发出 N+1 请求才能显示完整的项目列表。

I'm working on a new REST-ful API who's primary/only consumer will be a smart/non-web-browser client. I have a collection resource that is maintained/updated by background processes, not by the client itself. The only content type needed for the first iteration is JSON. The URIs are something like:

  • /items/ - Resource representing the collection of items.
  • /items/123 - Resource representing the individual item with ID 123.

Although the client will not be creating new items, or updating the collection to add/remove items, it will be updating some of the values in the individual items. My plan is to use HTTP PATCH to update item resources, using my own JSON patch format.

There will be many concurrent clients reading the items, and concurrent updates to different items, with occasional concurrent updates to the same item, and although a certain degree of "eventual consistency" is allowed, I would like to design this in as "cache friendly" a way as possible. Reading the RFC for PATCH, I see that on a successful response to PATCH, the cache of the Request-URI should be updated with the response, if there is one. The question comes down to:

Do I:

A) include the full representation of the individual items in the /items/ collection resource JSON representation, and send the PATCH to the /items/ URI and include the item to update in the patch format?

PROS:

  • This allows the client to not have to do N number of requests just to display the listing of resources
  • lets any cache of items be invalidated when a client updates an item.

CONS:

  • This isn't as "clean" to me, as I'm not really updating the collection, but an individual item.
  • This invalidates the cache of the whole collection, instead of the cache of the single item that changed.

OR

B) In the JSON representaiton of the resource collection, only include links to the items included, and have the client request the individual items after discovering which ones are in the collection. HTTP PATCH would be sent to the individual item URI (e.g. /items/123)

PROS:

  • Caching of the collection and item resources independently. PATCH of an individual item can properly invalidate the cache of just that item.
  • API is clearer, since you issue an HTTP PATCH on the specific item you want to update.

CONS:

  • Does not allow for batch updates to items. This is not currently a requirement at all, and I don't foresee it in the future, but only hindsight is 20-20.
  • Requires the client to issue N+1 requests to display the full list of items.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

梦巷 2024-12-19 05:13:39

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

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

I would go for B. But are you clients usually asking for all the collection (I mean do they need the collection) ? if not A option would be generating way too much traffic. And invalidation of cache occurs for all of the items (as they are in the collection).

If your clients mostly get the whole collection then A with a query param for the specific item is also an option.

心碎的声音 2024-12-19 05:13:39

我曾经有过类似的需求,客户想了解最新更新的项目。为此,我使用“上次更新”参数增强了我的集合资源:


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

然后需要将这个modifiedAfter信息附加到后端某处的项目数据。 Api 客户端可以自己决定他们想要抓取多少或多远的过去。完整查询和增量查询都很容易实现。

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

最后,在集合资源上使用 modifiedAfter,服务器端和 api 客户端都很满意。

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

I once had similar requirement, a client wanted to know the latest updated items. For that I enhanced my collection resource with a 'last-updated' param:


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

This modifiedAfter info then needs to be attached to the item-data somewhere in the backend. Api-Clients can themselves decide how much or how far in past they want to grab. Both full and delta-queries are easy to implement.

Trying to work with PATCH and caching on collections was very hard and far from trivial (working with standard E-Tag headers, showing the "right" items of interest etc., hard client implementation). Main problem is, that collections often have very dynamic and changing behaviour.

In the end working with modifiedAfter on collection-resources both server and api-client sides were happy.

Apart from the caching question evaluate whether you really need partial updates. In most cases I prefer the more simple full update (using PUT).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文