rest - 如果资源不存在,HTTP PUT 是否应该创建资源?

标签 rest http put

假设有人在我的端点上执行了一个PUT请求:

/resources/{id}

但是,在我的 PostgreSQL 数据库中没有存储具有给定 ID 的资源。

根据RFC 2616 ,如果我有能力,我应该创建资源:

The PUT method requests that the enclosed entity be stored under the supplied Request-URI. If the Request-URI refers to an already existing resource, the enclosed entity SHOULD be considered as a modified version of the one residing on the origin server. If the Request-URI does not point to an existing resource, and that URI is capable of being defined as a new resource by the requesting user agent, the origin server can create the resource with that URI.

可以使用提供的 ID 创建资源吗?因为在数据库插入时手动分配 ID 不是最佳实践。

如果无法创建资源,我是否应该返回 404 错误?

最佳答案

首先,您使用的是过时文档:RFC 2616 如今已不再适用,任何使用此类文档作为引用的人都应该立即停止。 p>

引用 Mark Nottingham在撰写本文时,谁是 IETF HTTP 和 QUIC 工作组的联合主席:

Don’t use RFC2616. Delete it from your hard drives, bookmarks, and burn (or responsibly recycle) any copies that are printed out.

旧的 RFC 2616 已被以下文档所取代,这些文档共同定义了 HTTP/1.1 协议(protocol):

如果您正在寻找方法、状态代码和 header 定义,那么 RFC 7231是您应该引用的文档。


话虽如此,让我们回到您的问题。

Should HTTP PUT create a resource if it does not exist?

视情况而定。

但是,如果您的应用程序代表客户端生成资源标识符,正如您在问题中提到的,那么您应该使用 POST而不是 PUT用于创建资源。

PUT 的某些部分方法定义引用如下。最后一句话似乎与你最相关(highlight 是我的),支持我上面刚刚提到的内容:

4.3.4. PUT

The PUT method requests that the state of the target resource be created or replaced with the state defined by the representation enclosed in the request message payload. [...]

If the target resource does not have a current representation and the PUT successfully creates one, then the origin server MUST inform the user agent by sending a 201 (Created) response. If the target resource does have a current representation and that representation is successfully modified in accordance with the state of the enclosed representation, then the origin server MUST send either a 200 (OK) or a 204 (No Content) response to indicate successful completion of the request. [...]

Proper interpretation of a PUT request presumes that the user agent knows which target resource is desired. A service that selects a proper URI on behalf of the client, after receiving a state-changing request, SHOULD be implemented using the POST method rather than PUT. [...]


Should I return a 404 error if the creation of the resource is not possible?

这似乎是要返回的准确状态代码,因为没有找到所请求资源的表示形式:

6.5.4. 404 Not Found

The 404 (Not Found) status code indicates that the origin server did not find a current representation for the target resource or is not willing to disclose that one exists. [...]


现在,为了完整起见,请在下面找到关于 POST 的一些相关引述。方法定义,应该用于在您的问题中描述的场景中创建资源:

4.3.3. POST

The POST method requests that the target resource process the representation enclosed in the request according to the resource's own specific semantics. For example, POST is used for the following functions (among others):

[...]

  • Creating a new resource that has yet to be identified by the origin server;

[...]

If one or more resources has been created on the origin server as a result of successfully processing a POST request, the origin server SHOULD send a 201 (Created) response containing a Location header field that provides an identifier for the primary resource created and a representation that describes the status of the request while referring to the new resource(s).

虽然201状态代码表示已创建新资源,Location header 指示新创建的资源所在的位置。如果没有 Location提供了 header ,那么客户端应该假定该资源是由有效请求 URI 标识的:

6.3.2. 201 Created

The 201 (Created) status code indicates that the request has been fulfilled and has resulted in one or more new resources being created. The primary resource created by the request is identified by either a Location header field in the response or, if no Location field is received, by the effective request URI. [...]

关于rest - 如果资源不存在,HTTP PUT 是否应该创建资源?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56240547/

相关文章:

php - 带有 GET 参数的 URL 格式?

http - RESTful PUT 如果不存在?

php - 在 symfony 'php://input' 中测试 PUT 为空

java - 读取HDFS并存储HBase时为"java.io.IOException: Pass a Delete or a Put"

json - 属性不存在时在 REST JSON API 上 POST/PUT

spring - 我的api/登录帖子在Spring安全的Grails 3上遭到未授权

spring - 使用与 Spring MVC 的内容协商进行 REST API 版本控制

rest - Orientdb REST API 仅返回 20 条记录

AngularJS 读取 web.config 值

http - Go 服务器中并发(同时)HTTP 连接的理论最大数量是多少?