如果HTTP PUT不存在,应该创建一个资源吗?

Zuc*_*cca 3 rest http put

假设有人PUT对我的Endint 执行请求:

/resources/{id}
Run Code Online (Sandbox Code Playgroud)

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

根据RFC 2616,如果我能够执行以下操作,则应创建资源:

PUT方法请求将封闭的实体存储在提供的Request-URI下。如果Request-URI引用了已经存在的资源,则应将封闭的实体视为驻留在原始服务器上的实体的修改版本。如果Request-URI没有指向现有资源,并且请求用户代理能够将该URI定义为新资源,则原始服务器可以使用该URI创建资源。

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

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

cas*_*lin 10

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

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

不要使用RFC2616。从硬盘驱动器,书签中将其删除,并刻录(或负责地回收)所有打印出的副本。

下列定义了HTTP / 1.1协议的文档已取代了旧的RFC 2616:

如果要查找方法,状态代码和标头定义,则 RFC 7231是您应参考的文档。


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

如果PUT资源不存在,HTTP应该创建一个资源吗?

这取决于。

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

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

4.3.4。放

PUT方法请求创建目标资源的状态或将其替换为请求消息有效负载中包含的表示形式所定义的状态。[...]

如果目标资源没有当前表示形式并且PUT成功创建了一个表示形式,则源服务器务必通过发送201(已创建)响应来通知用户代理。如果目标资源确实具有当前表示形式并且该表示形式已根据所包含表示形式的状态成功进行了修改,则原始服务器务必发送200(OK)或204(No Content)响应以指示请求已成功完成。[...]

PUT请求的正确解释假定用户代理知道需要哪个目标资源。 在收到状态更改请求后,代表客户选择适当URI的服务应使用POST方法而不是实现PUT[...]


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

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

6.5.4。找不到404

404(未找到)状态代码表示原始服务器没有找到目标资源的电流表示或不愿意透露一个存在。[...]


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

4.3.3。开机自检

POST方法要求目标资源根据资源自身的特定语义来处理请求中包含的表示形式。例如,POST用于以下功能(以及其他功能):

[...]

  • 创建尚未由原始服务器识别的新资源;

[...]

如果由于成功处理POST请求而在原始服务器上创建了一个或多个资源,则原始服务器应发送201(已创建)响应,该响应包含一个Location标头字段,该标头字段提供所创建的主要资源的标识符以及描述该标头的表示形式引用新资源时的请求状态。

201状态代码指示已创建新资源时,Location标头指示新创建的资源位于何处。如果没有Location提供标头,则客户端应假定资源由有效请求URI标识:

6.3.2。创建了201

201(创建)状态代码表示该请求已经完成,并已导致正在创建一个或多个新的资源。由请求创建的主要资源由Location响应中的标头字段标识,或者如果未Location接收到字段,则由有效请求URI标识。[...]

  • 为了保持本答案的高技术水平:本答案中提到的所有 RFC 均已废弃。RFC-9110 已废弃以下 RFC:RFC-7230、RFC-7231、RFC-7232、RFC-7233、RFC-7235。RFC-9111 已废弃以下 RFC:RFC-7234。 (4认同)