Http 以RESTful方式递增资源计数器:PUT vs POST

Http 以RESTful方式递增资源计数器:PUT vs POST,http,rest,httpverbs,Http,Rest,Httpverbs,我有一个有计数器的资源。例如,让我们调用资源配置文件,计数器是该配置文件的视图数 根据,PUT请求应该用于资源创建或修改,并且应该是幂等的。如果我正在更新(比如)配置文件的名称,那么这种组合是可以的,因为我可以发出一个PUT请求,将名称设置为1000次,结果不会改变 对于这些标准PUT请求,我让浏览器执行以下操作: PUT /profiles/123?property=value&property2=value2 要递增计数器,可以按如下方式调用url: PUT /profiles/1

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

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

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

PUT /profiles/123?property=value&property2=value2
要递增计数器,可以按如下方式调用url:

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


我正在寻找指导/最佳实践。您只是作为帖子来做这件事吗?

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

要查看纵断面的所有视图,请执行以下操作:

获取/profiles/123/视图

要将视图添加到配置文件,请执行以下操作:

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

要更新现有视图,请执行以下操作:

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

要深入查看视图的详细信息,请执行以下操作:

获取/查看/815

要删除视图,请执行以下操作:

删除/查看/815

此外,由于您要求最佳实践,请确保您的RESTful系统是安全的

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

相反,创建一个包含参数试图建模的概念的媒体类型。为该媒体类型指定一个简洁、明确且描述性的名称。然后记录此媒体类型。在REST中公开查询参数的真正问题是,这种做法通常会导致带外通信,从而增加客户端和服务器之间的耦合

然后为您的系统提供一个统一的接口。例如,添加新资源总是一篇文章。更新资源始终是一个问题。Deleting是DELETE,getiing是GET


REST最难的部分是理解媒体类型是如何进入系统设计的(这也是菲尔丁因为时间不够而在他的论文中漏掉的部分)。如果您想了解使用和双文档媒体类型的超文本驱动系统的具体示例,请参阅。

我认为正确的答案是使用补丁。我没有看到任何其他人建议使用它来原子级地增加计数器,但我相信它说得很好:

PATCH方法类似于PUT,只是实体包含 资源的原始版本之间的差异列表 由请求URI和所需资源内容标识 应用修补程序操作后。差异列表如下所示 采用实体媒体类型定义的格式(例如。, “应用程序/差异”),并且必须包含足够的信息,以允许 服务器重新创建转换原始文件所需的更改 将资源的版本设置为所需的版本

因此,要更新profile 123的视图计数,我将:

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

views + 1
其中,
x-counters
媒体类型(我刚编的)由多行
字段运算符标量
元组组成<代码>视图=500或
视图-1
视图+3
在语法上均有效(但在语义上可能被禁止)


我能理解一些人对制作另一种媒体类型的不满,但我谦虚地建议,它比POST/PUT更为正确。为一个字段创建一个资源,使用它自己的URI,特别是它自己的细节(我没有真正保留,我只有一个整数)对我来说是错误和麻烦的。如果我有23个不同的计数器要维护呢?

我认为Yanic和Rich的两种方法是相互关联的。修补程序不需要是安全的或独立的,但可以是安全的或独立的,以便对并发性更具鲁棒性。Rich的解决方案当然更易于在“标准”RESTAPI中使用

见:

修补程序既不安全,也不是[RFC2616]第节定义的幂等元 9.1

补丁请求可以以幂等的方式发出, 这也有助于防止两个系统之间的冲突造成不良后果 在相似的时间范围内对同一资源进行修补请求。 来自多个修补程序请求的冲突可能比 放置冲突,因为某些修补程序格式需要从 已知基点,否则将损坏资源


在评估了之前的答案后,我认为补丁不合适,而且,就我而言,为一项琐碎的任务摆弄内容类型是违反规则的。我只需要增加n+1,所以我就这样做了:

PUT /profiles/123$views
++
其中,
++
是消息正文,控制器将其解释为将资源增加1的指令


我选择了
$
来消除资源的字段/属性,因为它是一个,而且,就我而言,似乎比
/
更直观,在我看来,它具有可遍历性。

只是为了澄清一下:/views/815指的是对配置文件的815次查看,是吗?与标准有一点不同,因为没有“应用补丁操作后所需的资源内容”。例如,实体是要执行的指令,而不是所需的结果。根据@Pocketsand的说法,这种方法是否违反了“统一接口”下的“通过表示操纵资源”子约束“约束?您应该在其中发回要查看的资源的表示,inst