REST更新最佳实践:正文中没有id的PUT集合/:id VS正文中包括id的PUT集合/:id

我正在尝试为我正在研究的项目上的PUT请求定义约定,因此我无法决定这两个选项中的哪一个最合适,或者是否是个人喜好。我看过多篇有关REST最佳实践的文章,而且似乎总是将ID隐含为PUT请求的URL的一部分。

目标:通过REST API更新资源。

选项

  1. PUT收集/ {id}-体内没有id
  2. PUT集合/-URL中没有ID,仅在正文中

问题

  1. 我应该使用哪个约定?
  2. 为什么?
  3. 每种选择是否有普遍适用的利弊?
bajo42 回答:REST更新最佳实践:正文中没有id的PUT集合/:id VS正文中包括id的PUT集合/:id

确保您了解PUT

的语义很重要

对给定表示形式的成功PUT建议,在同一目标资源上进行后续GET将导致在200(OK)响应中发送等效表示形式。

换句话说

PUT /collection

表示“用此消息中包含的表示形式替换/ collection的表示形式”。

因此,如果您尝试修改集合资源本身的表示形式,那将是正确的请求,而如果您试图修改其他内容的表示形式,这将是错误的选择。

例如,如果集合的表示形式是其元素描述的列表,则可以使用PUT将列表替换为另一列表。

GET /collection

200 OK

[1,2,3]

PUT /collection

[4,5]

204 No Content

GET /collection

[4,5]

换句话说,从REST的角度来看,“集合”使用的资源与其他资源一样,具有相同的语义。

如果您要描述的是对其他资源的更改,则可以使用该资源的标识符

PUT /collection/1

现在,标识符中是否应包含标识符“ 1”?这取决于-但是这是基本规则:消费者(和中间组件)永远不要仅从表示形式中尝试从URI中提取信息。因此,如果您的消费者用例需要“ 1”,那么它需要出现在资源的表示形式中。

从这个意义上讲,PUT只是GET的双重功能-如果GET需要在响应提供的表示中包含信息,那么PUT需要在请求提供的表示中包含相同信息。

考虑文件内容可能会很有用-我们将读者需要的信息放入文件中,文件名/路径仅告诉读者如何找到它。或者,如果您想到的是Hash / Map / Dictionary,则该键用于将值获取到地图中或从地图中获取,但是信息在值中。

如果我不打算支持完整的收藏夹替换

...然后PUT /collection错误,因为我们都同意(通过RFC 7231)PUT的意思是“替换”。

It's okay to use POST,而不是PUT,如果您尝试以某种非标准化的方式操作/collection

如果您打算操纵集合的表示形式,但是想要描述插入和删除操作,而不是每次都发送完整的表示形式,则可以将PATCH与描述您所做更改的某种补丁文档一起使用

,

REST在大多数情况下都依赖于其传输层(HTTP)的语义。 HTTP的核心只是一个远程文档管理系统,它只是负责以无状态方式将文件从一个位置发送到另一个位置。正如Jim Webber所指出的,得出的任何业务规则基本上只是实际文档管理的副作用。

这样,您应该首先从常规文档管理的角度查看任务。您将文件放在某个位置并替换任何现有的表示形式。这就是PUT的实际含义。因此,文档ID并不是最好的主意,只要它不是实际文档内容的一部分即可。

在REST体系结构中,URI是否包含单独的标识符并不重要。更正式地说,整个URI是资源本身的标识符,无论是否在URI中放入其他ID。 URI既不应该告诉客户端有关资源或其语义的任何信息,也不应该告知任何层次结构。内容类型协商和链接关系是存在的。

菲尔丁甚至说

REST API不得定义固定的资源名称或层次结构(客户端和服务器之间明显的耦合)。服务器必须具有控制自己的名称空间的自由。而是允许服务器通过在媒体类型和链接关系中定义那些指令来指导客户端如何构造适当的URI(例如以HTML表单和URI模板完成)。 [此处失败表示,由于带外信息(例如,特定于域的标准,它是面向数据的等同于RPC的功能耦合),客户正在假设资源结构]。 (Source

许多开发人员将ID放入其URI的原因基本上是在服务器端,他们对URI进行令牌化,并使用相应的令牌对相应的段执行数据库查找。之所以不将即productID放入URI,是因为无论出于何种原因ID发生变化,尽管实际产品保持完全相同,但URI仍会作为结果事件而发生变化。即想起产品A000123,它突然被称为P12300001,但没有其他改变。这可能是由于公司合并等引起的(过去曾发生过这样的事件)。在REST体系结构中,诸如/products/A000123/products/P12300001之类的URI指的是两个不同的资源,因此指的是两个不同的产品,即使它们可能返回相同的内容。如果将使用另一个任意的UUID代替产品标识符,从而导致该UUID到productId的内部映射,则URI可能保持不变,因为基本上产品也保持不变。

到目前为止,我将重新解释您的问题:“您的客户真的需要ID吗?”。在理想的REST体系结构中,服务器将在过程的任何步骤向客户端教授客户端能够执行和允许执行的操作。由于REST基本上只是Web上使用的概念的概括,因此可以对整个设计进行建模,就好像交互应该在Web上进行,然后对应用程序交互使用相同的概念。考虑一个任意的客户端,无论是人工驱动还是机器驱动的,都应该从亚马逊订购一些商品,即,客户端要求亚马逊提供与某些搜索条件匹配的产品列表,服务器会以一个页面进行响应,该页面包含指向客户端的或多或少匹配产品的链接可以进一步深入了解每个产品的详细信息。如果有兴趣,客户可以通过单击链接将产品添加到其购物车中。实际上,它并不关心URI的外观,它只是通过一些元数据(文本或链接关系名称)声明将其添加到购物车中来调用它。客户从来没有对真正的产品编号真正感兴趣,因此为什么要添加它,而不是让客户(人工交互者)出于与代理人等进行电子邮件交互时的推荐原因而使用它。

最后,无论您是使用URI中的ID还是正文有效负载,都是您的个人选择。取决于您的用例,甚至没有必要将ID公开给客户端,因为REST(和Web)中使用的整个交互模型仅使用URI来检索数据的下一个“页面”以及是否使用该URI的提示。保留在URI随附的元数据中,例如链接内容的摘要文本(如HTML链接),或作为链接关系名称的一部分,这些链接名称由媒体类型定义,由Web linking extensions(例如作为Dublin Core)或standardization authority

,

PUT替换指定uri处的资源。

因此,如果您PUT collection,我希望整个集合都将被覆盖。

所以这实际上不是意见问题,在这种情况下,这完全是错误的事情。

本文链接:https://www.f2er.com/2617120.html

大家都在问