我在服务器中为客户端保留了一个键值存储。如果用户发送密钥“k1”,那么我将它插入到数据库中。这是考虑POST
还是PUT
?
此外,我还有另一个操作删除所有现有密钥并添加新密钥。这是因为它清除了记录并添加了一个新记录POST
。PUT
根据HTTP 规范:
PUT 方法请求将封闭的实体存储在提供的 Request-URI 下。如果 Request-URI 引用了一个已经存在的资源,封闭的实体应该被认为是在源服务器上的一个修改版本。如果 Request-URI 不指向现有资源,并且该 URI 能够被请求用户代理定义为新资源,则源服务器可以使用该 URI 创建资源。
因此,我认为使用 PUT 进行插入或更新是完全合法的,前提是在这两种情况下都事先知道 URI。如果您将密钥用作 URI 的一部分(如http://www.somewhere.com/resources/k1中的 k1 ),则应该是这种情况。然而,为了实现理想的 RESTful,对同一 URL 的 GET 还应该允许您下载资源。
我不认为这个操作可以被认为是 RESTful,因为它做了两件事。它似乎提供了一个宏来满足特定客户端的需求,而不是简单地访问数据。一个标准的 RESTful 设计将是
不太明确,但我认为通过向http://www.somewhere.com/resources发送单个 DELETE 请求来删除所有资源也是合法的。
Polly Shaw 的回答是正确的,但我想提一下,鉴于消息很可能不完整(在尚未创建资源时缺少 ID),PATCH动词会稍微正确一些。
https://www.rfc-editor.org/rfc/rfc5789
这是非常精细的调整。
如果 upsert 的定义是新记录与现有记录的混合(要更新)。
参考:https ://restfulapi.net/rest-put-vs-post/
PUT 需要是幂等的。这意味着如果您第二次 PUT 相同的有效负载,则不应更改系统状态。
如果预期的有效负载是新的和现有的混合,并且预期的行为将是第二次创建更多新记录,那么看起来“upsert”将与 POST 更紧密地对齐。
我们努力创建容错 API。如果你不能使 PUT 幂等并且他们必须使用它,他们可能会破坏系统。另一方面,POST 预计不会是幂等的,因此如果您在有效负载中(一遍又一遍)发送仅更新数据(即使这在技术上违反了 POST 的幂等性规则,因为它没有通过以下方式更改系统的状态)在后续调用中添加记录)系统将(可能)不会被破坏。
如果你真的想实现一个 upsert,两者都不是完美的,但如果错误导致 PUT 上的损坏,那么 API 是罪魁祸首(它应该是幂等的),而 POST 上的损坏是“我告诉过你的”。
我也喜欢思考 API 使用者会寻找什么。通常,在新屏幕上工作的 UI 开发人员会寻找添加用户在 UI 中添加的记录。他将首先寻找一个 POST,然后发现它也处理等式的 PUT 方面。
所以,两者都不是,但如果您必须选择,请选择 POST。
upsert 操作背后的想法是客户端拥有关于/决定数据结构的信息并发送带有键值的数据。因此 upsert 操作的请求模型与包含 key 的更新操作非常相似,如下例所示:
/customers/jimmy
更新现有记录的预期方法是 PUT。所以你的选择应该是PUT。
POST 通常用于插入具有全新内容的新记录,如下例所示:
POST /customers HTTP/1.1
Content-Type: ...
Content-Length: ...
Host: server.yourdomain.com
Accept: ...
User-Agent: ...
id jimmy
name jimmy
Occupation Stackoverflower
因此,在您的情况下,您不需要任何 POST 操作,因为用于 upsert 操作的 PUT 也涵盖了这一点。
在这里,关于 upsert 的关键问题是您信任客户对 upsert 操作的可能性有多大。如果客户希望使用现有键插入新记录,会发生什么?在您的情况下,您应该将此请求作为更新处理,因为插入和更新请求都来自同一个 api,并且您有一条现有记录。这是关于设计的问题。
根据MDN 网络文档:
HTTP PUT 请求方法创建新资源或用请求有效负载替换目标资源的表示。
PUT
和之间的区别POST
是PUT
幂等的:连续调用一次或多次具有相同的效果(即没有副作用),而连续的相同POST
请求可能具有附加效果,类似于多次下订单。
PUT /new.html HTTP/1.1
PUT /new.html HTTP/1.1
Host: example.com
Content-type: text/html
Content-length: 16
<p>New File</p>
如果目标资源没有当前表示并且 PUT 请求成功创建了一个,则源服务器必须通过发送201
( Created
) 响应来通知用户代理。
HTTP/1.1 201 Created
Content-Location: /new.html
如果目标资源确实具有当前表示并且该表示已根据封闭表示的状态成功修改,则源服务器必须发送200
( OK
) 或204
( No Content
) 响应以指示请求成功完成。
HTTP/1.1 204 No Content
Content-Location: /existing.html
如果你混合一切,你可能没有在做 REST。来自RESTful Web 服务:基础知识 POST
并PUT
具有不同的使用场景:
To create a resource on the server, use POST. To retrieve a resource, use GET. To change the state of a resource or to update it, use PUT. To remove or delete a resource, use DELETE.
因此,请考虑POST
将新票张贴到博客并PUT
更改现有值。
删除应该作为DELETE
动词的独特操作来完成。在更新之前“全部删除”听起来不是一个好主意。