26

我有一个有计数器的资源。举个例子,让我们调用资源配置文件,计数器是该配置文件的视图数。

根据REST wiki,PUT 请求应该用于资源创建或修改,并且应该是幂等的。如果我要更新配置文件的名称,那么这种组合很好,因为我可以发出一个 PUT 请求,将名称设置为 1000 次,结果不会改变。

对于这些标准 PUT 请求,我让浏览器执行以下操作:

PUT /profiles/123?property=value&property2=value2

为了增加一个计数器,可以像这样调用 url:

PUT /profiles/123/?counter=views

每次调用都会导致计数器递增。从技术上讲,这是一个更新操作,但它违反了幂等性。

我正在寻找指导/最佳实践。您只是将其作为 POST 吗?

4

4 回答 4

14

我认为正确的答案是使用 PATCH。我没有看到其他人建议应该使用它来原子地递增计数器,但我相信RFC 2068说得很好:

PATCH 方法类似于 PUT,除了实体包含由 Request-URI 标识的资源的原始版本与应用 PATCH 操作后资源的所需内容之间的差异列表。差异列表采用由实体的媒体类型定义的格式(例如,“application/diff”),并且必须包含足够的信息以允许服务器重新创建将资源的原始版本转换为所需版本所需的更改版本。

因此,要更新配置文件 123 的查看次数,我会:

PATCH /profiles/123 HTTP/1.1
Host: www.example.com
Content-Type: application/x-counters

views + 1

媒体x-counters类型(我刚刚编写的)由多行field operator scalar元组组成。views = 500or or views - 1orviews + 3在句法上都是有效的(但在语义上可能是被禁止的)。

我可以理解一些对编造另一种媒体类型的不满,但我谦虚地建议它比 POST / PUT 替代方案更正确。为一个字段构建一个资源,包含它自己的 URI,尤其是它自己的详细信息(我并没有真正保留,我只有一个整数)对我来说听起来是错误的和麻烦的。如果我有 23 个不同的计数器需要维护怎么办?

于 2012-02-08T13:14:47.053 回答
10

另一种方法可能是向系统添加另一个资源以跟踪个人资料的查看情况。你可以称之为“观看”。

要查看个人资料的所有查看:

获取 /profiles/123/viewings

要将查看添加到配置文件:

POST /profiles/123/viewings #在这里,您将使用请求正文中的自定义媒体类型提交详细信息。

要更新现有查看:

PUT /viewings/815 # 使用您创建的自定义媒体类型在请求正文中提交修改后的查看属性。

要深入了解查看的详细信息:

获取 /viewings/815

要删除查看:

删除 /viewings/815

此外,由于您要求最佳实践,请确保您的 RESTful 系统是超文本驱动的

在大多数情况下,在 URI 中使用查询参数并没有错——只是不要让您的客户认为他们可以操纵它们。

相反,创建一个体现参数试图建模的概念的媒体类型。给这个媒体类型一个简洁、明确和描述性的名称。然后记录此媒体类型。在 REST 中暴露查询参数的真正问题是这种做法经常导致带外通信,因此增加了客户端和服务器之间的耦合。

然后给你的系统一个统一的界面。例如,添加新资源始终是 POST。更新资源始终是 PUT。删除就是DELETE,getiing就是GET。

关于 REST 最难的部分是理解媒体类型如何融入系统设计(这也是菲尔丁在他的论文中因为时间用完而遗漏的部分)。如果您需要使用和记录媒体类型的超文本驱动系统的特定示例,请参阅Sun Cloud API

于 2009-09-15T14:41:54.537 回答
1

在评估了之前的答案后,我认为 PATCH 是不合适的,并且就我的目的而言,为了一项琐碎的任务而摆弄 Content-Type 违反了KISS 原则。我只需要增加 n+1 所以我这样做了:

PUT /profiles/123$views
++

消息正文在哪里++,控制器将其解释为将资源加一的指令。

我选择$划分资源的字段/属性,因为它是一个合法的子分隔符,并且,就我的目的而言,它似乎比/我认为具有可遍历性的更直观。

于 2017-06-30T17:35:32.607 回答
0

我认为 Yanic 和 Rich 的两种方法都很有趣。PATCH 不需要是安全的或非幂等的,但可以是为了更健壮地对抗并发。Rich 的解决方案当然更容易在“标准”REST API 中使用。

请参阅RFC5789

正如 [RFC2616] 第 9.1 节所定义的那样,PATCH 既不安全也不幂等。

可以以幂等的方式发出 PATCH 请求,这也有助于防止在相似时间范围内同一资源上的两个 PATCH 请求之间发生冲突而导致不良结果。来自多个 PATCH 请求的冲突可能比 PUT 冲突更危险,因为某些补丁格式需要从已知的基点进行操作,否则它们会破坏资源。

于 2015-07-03T15:05:35.947 回答