REST PUT与POST在UUID上的区别

8
如果我使用UUID作为我的REST端点URI的一部分来标识实体:
/entities/<uuid>/

当创建新实体时,客户端生成UUID,在使用PUTPOST方面是否有最佳实践?换句话说,UUID由客户端生成,而不是由服务器生成。
如果我使用PUT,那么消息有效载荷是否应该包含UUID?在这种情况下,消息和标识实体的URI都将包含UUID
有关规范,请参见:REST RFC

1
你把“REST”和“HTTP”混淆了。没有“REST RFC”。有一个“HTTP RFC”,但现在它不再是RFC 2616了。 - Julian Reschke
3个回答

4
由于您(客户端)已经知道UUID,我建议使用PUT是最佳实践,您不需要在负载中包含UUID。诚然,在PUTPOST之间存在一些争议,并且反复阅读RFC并不能完全澄清这一点。但我认为前面的说法是正统的。
请参见PUT vs POST in REST进行深入讨论。

“你不需要在有效载荷中包含UUID”这是真的吗?这似乎与@nikita所说的相矛盾,因为UUID是资源表示的一部分,所以需要包含它。 - Alex Rothberg
资源的名称不需要成为表示的一部分。 - Julian Reschke

1
了解PUT和POST之间的区别。
PUT旨在使用新资源(http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.6)替换URI指向的资源。它是幂等的,即无论您使用相同的有效负载调用多少次,结果都相同;它将通过URI使相同的资源可用。
因此,如果资源不存在,则创建一个新资源。即使在这种情况下,结果也是相同的,即它将通过URI使相同的资源可用。
POST旨在为URI指向的资源创建子资源(http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.5)。如果资源是列表,则会向其添加项目。如果它是项目,则应该向项目添加某些内容,例如属性。
如果URI指向的项目不可用,最好是一个错误条件,例如“404”。POST的目的在于向现有资源添加内容。
针对您的问题,根据上述说明,最好使用“/entities/”作为URI来使用POST。不应该在URI中使用不存在的资源UUID。如果您使用PUT,则应使用“/entities/”。
POST /entities/ HTTP/1.1
Content-Type: application/json
{
   UUID: <UUID>..
   OtherStuff: ...
}

PUT /entities/<UUID> HTTP/1.1
Content-Type: application/json
{
   UUID: <UUID>..
   OtherStuff: ...
}

响应应该相同

HTTP/1.1 201 Created
Location: http://www.examples.com/entities/<uuid>/

虽然PUT是幂等的,但如果再次使用PUT方法,则应在响应中使用200或204。

你的第二个问题:理想情况下,完整的资源细节应该在PUT负载中,而不仅仅是URI。


你提出了两种创建新资源的方式:没有UUID的POST和带有UUID的PUT。在客户端生成UUID的情况下,哪种方式更受推荐? - Alex Rothberg
1
我更喜欢使用没有UUID的POST来创建新资源。因为我一直保持URI应指向现有资源的方式,这样我就不会混淆。另外,为了使PUT真正成为幂等操作,如果负载相同,它应始终返回相同的响应。但是,如果您使用PUT创建新资源并进行更新,则将返回两种不同类型的响应。在创建时它是201,否则它是200。这破坏了语义。 - Pankaj Jangid

-1

POST和PUT的主要区别:

POST用于追加新实体。POST不是幂等的。这意味着如果您发送10次POST请求,您将创建10个不同的实体。通常,您应该获得201(已创建)响应代码以及指向新创建资源的URL的位置标头来响应POST请求。在您的情况下,我建议您将其POST到类似于以下URL的位置

POST /entities/ HTTP/1.1
Content-Type: application/json
{
   UUID: <UUID>..
   OtherStuff: ...
}

响应:

HTTP/1.1 201 Created
Location: http://www.myREST/entities/<uuid>/

PUT请求用于修改现有状态。PUT是幂等的。通常会收到200(OK)响应代码。

您需要在PUT / POST负载中包含UUID。 UUID是资源表示的一部分。 PUT和POST都将表示传输到REST服务器以更改/追加资源状态。

顺便说一下,在REST中不应使用URI术语。 URI可能没有表示,但URL始终具有表示。


如果我在UUID上有一个唯一性约束,会改变任何东西吗(这基本上是必须的,因为我依赖UUID作为实体的规范查找)?因此,如果我尝试多次POST相同的UUID,则只有第一个成功201。如果我使用PUT来创建,我应该担心/关心的是URL和载荷均包含(希望)相同的UUID吗? - Alex Rothberg
你的意思是在 PUT 中应该包含 UUID 吗?可能因为 URL 不包括 UUID,所以你必须在 POST 中包含它。 - Alex Rothberg
在这种情况下,您不应该依赖URL。REST不规定URL的格式。它可能是完全随机的。将PUT视为SQL UPDATE语句。当您执行UPDATE时,总是会添加WHERE ID='<UUID>'子句,对吧? - nikita
1
好的。假设我在每个请求(PUT或POST)中都包含UUID,如果我在客户端生成UUID,那么我应该在创建时使用哪个:PUT还是POST? - Alex Rothberg
POST表示插入,PUT表示更新。 - nikita
显示剩余8条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接