我有一个有计数器的资源.为了举例,让我们调用资源配置文件,计数器是该配置文件的视图数.
根据REST维基,PUT请求应该用于资源创建或修改,并且应该是幂等的.如果我正在更新配置文件的名称,那么这种组合很好,因为我可以发出一个PUT请求,将名称设置为1000次,结果不会改变.
对于这些标准PUT请求,我有浏览器做类似的事情:
PUT /profiles/123?property=value&property2=value2
对于递增计数器,可以像这样调用url:
PUT /profiles/123/?counter=views
每次调用都会导致计数器递增.从技术上讲,这是一个更新操作,但它违反了幂等性.
我正在寻找指导/最佳实践.你刚才这样做了吗?
我认为正确的答案是使用PATCH.我没有看到有人推荐它应该用于原子地递增计数器,但我相信RFC 2068说得很好:
PATCH方法类似于PUT,除了实体包含在应用PATCH动作之后由Request-URI标识的资源的原始版本与资源的期望内容之间的差异列表.差异列表采用由实体的媒体类型定义的格式(例如,"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 = 500
或views - 1
或views + 3
都是有效的语法(但可能在语义上禁止的).
我可以理解一些皱眉 - 组成另一种媒体类型,但我谦卑地建议它比POST/PUT替代方案更正确.构建一个字段的资源,完成它自己的URI,特别是它自己的细节(我没有真正保留,我只有一个整数)听起来错误和麻烦.如果我要维护23个不同的计数器怎么办?
另一种方法可能是向系统添加另一个资源以跟踪配置文件的查看.你可以称之为"观看".
要查看个人资料的所有视图:
GET/profiles/123 /查看
要向配置文件添加查看:
POST/profiles/123/viewings #here,您将在请求正文中使用自定义媒体类型提交详细信息.
要更新现有的查看:
PUT/viewings/815#使用您创建的自定义媒体类型在请求正文中提交Viewing的修订属性.
要深入了解查看的详细信息:
GET/viewings/815
删除查看:
DELETE/viewings/815
此外,因为您要求最佳实践,请确保您的RESTful系统是超文本驱动的.
在大多数情况下,在URI中使用查询参数没有任何问题 - 只是不要让客户知道他们可以操纵它们.
相反,创建一个介绍参数试图建模的概念的媒体类型.为此媒体类型提供简洁,明确和描述性的名称.然后记录此媒体类型.在REST中公开查询参数的真正问题是,这种做法经常导致带外通信,因此增加了客户端和服务器之间的耦合.
然后给你的系统一个统一的界面.例如,添加新资源始终是POST.更新资源始终是PUT.删除是DELETE,getiing是GET.
关于REST最难的部分是理解媒体类型如何影响系统设计(这也是Fielding因为时间不多而遗漏了论文的部分).如果您需要使用和描述媒体类型的超文本驱动系统的特定示例,请参阅Sun Cloud API.