背景信息分析:
根据 RFC 2616,第 9.5 条,POST 用于创建资源:
使用 POST 方法要求原始服务器接受请求中包含的实体作为请求-URI 在请求线中识别的资源的新子属。
根据 RFC 2616,第 9.6 条,PUT 用于创建或取代资源:
PUT 方法要求关闭的实体存储在提供的请求-URI. 如果请求-URI 提到已经存在的资源,关闭的实体 SHOULD 将被视为居住在原始服务器的修改版本. 如果请求-URI 没有指向现有资源,并且 URI 能够由请求用户年龄定义为新资源。
我的问题:
那么,哪种HTTP方法应该用于创建资源?或者两者都应该得到支持?
您应该使用 PATCH. 您应该使用 PATCH 等问题列表
PATCH /questions HTTP/1.1
包含您要创建的对象的列表,如
[
{
"title": "I said semantics!",
"content": "Is this serious?",
"answer": "Not really"
}
]
您将修改现有资源列表,而无需提供全新的内容,您将从不存在的数据转换为现有信息的状态,而无需提供所有数据(服务器最有可能将添加身份证)。
这个方法的一个很好的优点是,您可以使用单个请求创建多个实体,简单地将所有实体列入列表中。
一个缺点是,可能没有人这样使用PATCH,我害怕,我只是发明了它,但我希望,我提供了一个很好的论点。
至于语法,CREATE是IMHO的唯一正确选择,其余的一切都是一个圆洞的平方点,不幸的是,我们所有的都是圆洞。
最重要的考虑是可靠性. 如果一个 POST 消息丢失,系统的状态是不确定的. 自动恢复是不可能的. 对于 PUT 消息,状态是不确定的,直到第一次成功退出。
例如,使用 POST 创建信用卡交易可能不是一个好主意。
如果您在您的资源上有自动创建的 URI,您仍然可以使用 PUT 通过向客户端传输一个创建的 URI(指向一个空的资源)。
其他一些考虑:
POST 取消了所有包含资源的隐藏副本(更好的一致性) PUT 回复是不可隐藏的,而 POST 回复是(要求内容位置和终止) PUT 是不受 Java ME、旧浏览器、防火墙等支持。
我想添加我的“实用”建议. 使用 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
Create => HTTP PUT
Retrieve => HTTP GET
Update => HTTP POST
Delete => HTTP DELETE
事实上, CRUD 操作的 R(选择) 和 D(选择) 可以直接地图到 HTTP 方法 GET 和 DELETE 相应。 然而,混淆在 C(现实) 和 U(更新) 操作中。 在某些情况下,可以使用 PUT 为创建而在其他情况下需要 POST。
基于上述定义,我的使用 HTTP PUT 方法与使用 HTTP POST 方法为 REST 服务是: 使用 HTTP PUT 方法,当:
The client includes all aspect of the resource including the unique identifier to uniquely identify the resource. Example: creating a new employee.
The client provides all the information for a resource to be able to modify that resource.This implies that the server side does not update any aspect of the resource (such as an update date).
The server will provide some information concerning the newly created resource. For example, take a logging system. A new entry in the log will most likely have a numbering scheme which is determined on the server side. Upon creating a new log entry, the new sequence number will be determined by the server and not by the client.
On a modification of a resource, the server will provide such information as a resource state or an update date. Again in this case not all information was provided by the client and the resource will be changing from one modification request to the next. Hence a non idempotent operation.
结论
大多数时候,你会用它们如下:
POST a resource into a collection PUT a resource identified by collection/:id。
例如:
POST /items PUT /items/1234
请注意,POST在收藏中“创建”一个新的元素,而PUT在某个URL中“替换”一个元素,但使用PUT进行部分修改是一种非常常见的做法,也就是说,只使用它来更新现有资源,并仅修改体内所包含的字段(忽略其他字段)。
请记住,REST是一组条约和指导方针,以保持您的API简单。 如果您结束了一个复杂的工作周围,只需检查“RESTfull”框,那么您正在击败目的。
创建:
可以用 PUT 或 POST 进行如下:
更新:
只能以以下方式与PUT进行:
PUT 将资源更新为现有资源ID 作为识别器,在 / 资源 URI 或收集下。
例子: <-- 一般 - 具体 -> URI: website.example/users/john website.example - 整个网站用户 - 用户的收集 john - 收集的项目,或资源 URI:website.example/users/john/posts/23 website.example - 整个网站用户 - 用户的收集 john - 收集的项目,或资源帖子 - 收集的帖子 john 23
当你使用POST时,你总是提到收藏,所以每当你说:
POST /users HTTP/1.1
POST /users/john HTTP/1.1
它会工作,但你说你想在用户收藏下添加一个资源。
PUT /users/john HTTP/1.1
让我们来介绍一下特区的一些重要部分:
邮件
因此,它在收藏中创造了一个新的资源。
皮特
参考: