在REST中,POST或PUT最适合upsert操作吗?
我在服务器中为客户端保留一个键值存储。如果用户发送密钥“k1”,那么我将其插入数据库。这被认为是在REST中,POST或PUT最适合upsert操作吗?,rest,post,put,Rest,Post,Put,我在服务器中为客户端保留一个键值存储。如果用户发送密钥“k1”,那么我将其插入数据库。这被认为是POST还是PUT 我还有另一个操作,删除所有现有密钥并添加新密钥。这是POST还是PUT,因为它会清除记录并添加一个新记录。如果您混合所有内容,则可能没有执行REST。FromPOST和PUT具有不同的使用场景: 考虑 POST 将一张新的帖子张贴到一个博客上,放置改变现有的值。 应使用DELETE动词将删除作为一种独特的操作进行。因为在更新之前“全部删除”听起来不是个好主意。如果用户发送密钥“k1
POST
还是PUT
我还有另一个操作,删除所有现有密钥并添加新密钥。这是
POST
还是PUT
,因为它会清除记录并添加一个新记录。如果您混合所有内容,则可能没有执行REST。FromPOST
和PUT
具有不同的使用场景:
考虑<代码> POST <代码>将一张新的帖子张贴到一个博客上,<代码>放置改变现有的值。
应使用DELETE
动词将删除作为一种独特的操作进行。因为在更新之前“全部删除”听起来不是个好主意。如果用户发送密钥“k1”,那么我会将其插入数据库。这算是邮寄还是邮寄。
根据报告:
PUT方法请求将封闭的实体存储在提供的请求URI下。如果请求URI引用的是一个已经存在的资源,则应将包含的实体视为驻留在源服务器上的实体的修改版本。如果请求URI不指向现有资源,并且该URI能够由请求用户代理定义为新资源,则源服务器可以使用该URI创建资源
因此,我认为使用PUT进行插入或更新是完全合法的,前提是在这两种情况下,URI都是事先知道的。如果将键用作URI的一部分(如中的k1),则应该是这样。然而,为了实现理想的RESTful,访问同一URL也应该允许您下载资源
另外,我还有一个操作,删除所有现有的密钥并添加新的密钥,这是POST还是PUT,因为它清除记录并添加新的密钥。
我不认为这个操作可以被认为是RESTful的,因为它做了两件事。它似乎提供了一个宏来满足特定客户机的需求,而不是简单地访问数据。标准的RESTful设计是
不太清楚,但我认为通过向发送单个删除请求来删除所有资源也是合法的。upsert操作背后的思想是,客户机拥有关于/决定数据结构的信息,并发送带有键值的数据。因此,upsert操作的请求模型与update操作非常相似,包括键,如下例所示:
/customers/jimmy
POST /customers HTTP/1.1
Content-Type: ...
Content-Length: ...
Host: server.yourdomain.com
Accept: ...
User-Agent: ...
id jimmy
name jimmy
Occupation Stackoverflower
将放置更新现有记录的预期方法。所以你的选择应该放在第一位
POST通常用于插入具有全新内容的新记录,如以下示例所示:
/customers/jimmy
POST /customers HTTP/1.1
Content-Type: ...
Content-Length: ...
Host: server.yourdomain.com
Accept: ...
User-Agent: ...
id jimmy
name jimmy
Occupation Stackoverflower
所以在您的情况下,您不需要任何POST操作,因为PUT for upsert操作也涵盖了这一点
这里,有关upsert的关键问题是,您在upsert操作方面信任客户的可能性有多大。如果客户机希望使用现有密钥插入新记录,会发生什么情况?在您的情况下,应该将此请求作为更新处理,因为插入和更新请求都指向同一个api,并且您有一个现有记录。关于设计,这是您需要回答的问题。Polly Shaw的回答是正确的,但我想指出的是,考虑到消息很可能不完整(在尚未创建资源时缺少ID),使用修补程序动词会稍微正确一些
这是非常精细的调整。如果upsert的定义是新记录与现有记录的混合(要更新) 提及: PUT必须是幂等的。这意味着,如果再次放置相同的有效负载,则不应更改系统状态 如果预期的有效负载是新的和现有的混合,并且预期的行为是在第二次创建更多的新记录,那么它看起来“upsert”将与POST更紧密地对齐 我们努力创建容错API。如果不能使PUT幂等元,而他们必须使用它,则可能会损坏系统。另一方面,POST不应是幂等的,因此,如果您在有效负载中发送仅更新数据(一次又一次)(即使这在技术上违反了POST的幂等规则,因为它没有通过在后续调用中添加记录来更改系统的状态),则系统(可能)不会损坏
- 规范中说PUT“可以”添加新项,“必须”是幂等的
- 它说POST“必须”添加新项,并且不是幂等项
因此,两者都不是,但如果必须选择,请选择POST。我确实认为在某些情况下“upsert”是有效的,例如,如果用户“查看”了某个资源,则会进行标记,即我希望此“标记/选中/勾选”,而不管它以前的状态如何。对于5张反对票,此答案有什么问题?调用者可能会根据结果调用get,然后调用put或post。@RuntimeException我想这是因为,在upsert时(当一个端点应该更新一个资源,但如果该资源不存在,则创建该资源)会告诉我们同样的问题,并询问不同的场景。所以,它并没有回答问题,而是告诉了同样的事情,这已经很清楚了。@RuntimeException,也有点误导性地等同于