背景信息分析:

根据 RFC 2616,第 9.5 条,POST 用于创建资源:

使用 POST 方法要求原始服务器接受请求中包含的实体作为请求-URI 在请求线中识别的资源的新子属。

根据 RFC 2616,第 9.6 条,PUT 用于创建或取代资源:

PUT 方法要求关闭的实体存储在提供的请求-URI. 如果请求-URI 提到已经存在的资源,关闭的实体 SHOULD 将被视为居住在原始服务器的修改版本. 如果请求-URI 没有指向现有资源,并且 URI 能够由请求用户年龄定义为新资源。

我的问题:

那么,哪种HTTP方法应该用于创建资源?或者两者都应该得到支持?


当前回答

总结

参考

POST 和 PUT 方法之间的基本差异被关闭代表性的不同意图所突出。 POST 请求中的目标资源旨在根据资源的本质处理关闭代表性,而 PUT 请求中的关闭代表性则被定义为取代目标资源的状态。

但建议始终使用更专门的请求方法而不是 POST 适当时,因为它为中介提供更多信息,以自动化信息获取(因为 GET、HEAD、OPTIONS 和 TRACE 被定义为安全),处理通信故障(因为 GET、HEAD、PUT、DELETE、OPTIONS 和 TRACE 被定义为无效),并优化存储性能(因为 GET、HEAD、PUT、DELETE、OPTIONS 和 TRACE 被定义为无效)。

其他回答

您应该使用 PATCH. 您应该使用 PATCH 等问题列表

PATCH /questions HTTP/1.1

包含您要创建的对象的列表,如

[
    {
        "title": "I said semantics!",
        "content": "Is this serious?",
        "answer": "Not really"
    }
]

您将修改现有资源列表,而无需提供全新的内容,您将从不存在的数据转换为现有信息的状态,而无需提供所有数据(服务器最有可能将添加身份证)。

这个方法的一个很好的优点是,您可以使用单个请求创建多个实体,简单地将所有实体列入列表中。

一个缺点是,可能没有人这样使用PATCH,我害怕,我只是发明了它,但我希望,我提供了一个很好的论点。

至于语法,CREATE是IMHO的唯一正确选择,其余的一切都是一个圆洞的平方点,不幸的是,我们所有的都是圆洞。

POST 意思是“创建新”如在“这里是创建用户的输入,为我创建它”。

PUT 的意思是“输入,如果已经存在,取代”如“这里是用户数据5”。

您 POST 到 example.com/users 因为您还不知道用户的 URL,您希望服务器创建它。

您可以访问 example.com/users/id 因为您想要更换/创建一个特定的用户。

与相同数据两次发布意味着创建两个相同的用户与不同的ID。 与相同数据两次发布会创建用户的第一个,并更新到相同状态的第二次(没有变化)。 因为你结束相同状态后一个 PUT 无论你执行多少次,它被说是“平等强大”每次 - idempotent. 这是有用的自动退休

在恢复已经提到的风险下,似乎很重要的是要记住,PUT意味着客户端在创建资源时会控制什么URL。因此,PUT和POST之间的选择的一部分将是关于您可以信任客户端提供正确的,正常的URL,与您的URL计划是什么相一致。

当您无法完全信任客户端做正确的事情时,更适合使用 POST 创建一个新的项目,然后将 URL 返回客户端在回复中。

步骤6是人们通常会对该做什么感到困惑的地方. 但是,没有理由创建一个麻烦来解决这个问题. 相反,HTTP 可以按照 RFC 2616 所规定的方式使用,服务器回答:

409 Conflict 的状态代码是正确的使用,因为:

但是,相反是真的. 返回 303 只会是有意义的,如果多个创建请求(创建不同的资源)返回相同的内容. 一个例子将是一个“谢谢您提交您的请求消息”,客户不需要每次重新下载。

我想添加我的“实用”建议. 使用 PUT 当你知道“ID”可以恢复你正在储存的对象. 使用 PUT 不会工作太好,如果你需要, 说, 数据库创建的 ID 将被返回给你进行未来的搜索或更新。

因此: 保存现有用户,或者客户端创建 ID 的用户,并确认 ID 是独一无二的:

PUT /user/12345 HTTP/1.1  <-- create the user providing the id 12345
Host: mydomain.example

GET /user/12345 HTTP/1.1  <-- return that user
Host: mydomain.example

否则,使用 POST 首先创建对象,然后使用 PUT 更新对象:

POST /user HTTP/1.1   <--- create the user, server returns 12345
Host: mydomain.example

PUT /user/12345 HTTP/1.1  <--- update the user
Host: mydomain.example