所以HTTP规范说HTTP PUT和DELETE应该是幂等的。这意味着,对具有相同正文的同一URL的多个PUT请求不应导致服务器上的其他副作用。多个HTTP DELETE也是如此,如果将2个或更多DELETE请求发送到同一个URL,则第二个(或第三个等)请求不应返回指示资源已被删除的错误。
然而,在处理完DELETE之后PUT对URI的请求怎么办?它应该返回404吗?
例如,请考虑按以下顺序执行以下请求:
item
资源,返回HTTP 201和URI / api / items / 6 item
#6 item
#6并返回HTTP 202 那么,如果PUT与获取和返回404一致,或者@CodeCaster建议,那么409会更合适吗?
答案 0 :(得分:11)
RFC 2616,第9.6节,PUT:
POST和PUT请求之间的根本区别在于 反映在Request-URI的不同含义中。一个中的URI POST请求标识将处理随附的资源 实体。该资源可能是一个数据接受过程,一个网关 一些其他协议,或接受注释的单独实体。 相反,PUT请求中的URI标识所包含的实体 使用请求 - 用户代理知道URI的用途和 服务器不得尝试将请求应用于其他资源。
和
如果无法使用Request-URI创建或修改资源,则应该给出适当的错误响应,以反映问题的性质。
因此定义'适当'是看400系列,表明存在客户端错误。首先,我将消除不相关的:
那么,我们可以使用哪些?
服务器理解请求,但拒绝履行请求。 授权无效,请求不应重复。
这个描述实际上非常适合,尽管它通常用于与权限相关的上下文中(如:你可能不会......)。
服务器未找到与Request-URI匹配的任何内容。没有 指示该条件是暂时的还是 常驻。如果服务器应该使用410(Gone)状态代码 通过一些内部可配置的机制,知道一个旧的 资源永久不可用,没有转发地址。 此状态代码通常在服务器不希望时使用 明确说明请求被拒绝的原因,或者没有其他请求 回应是适用的。
这也是,尤其是最后一行。
请求行中指定的方法不允许使用 Request-URI标识的资源。响应必须包括一个 允许包含所请求的有效方法列表的标头 资源。
我们没有可以响应的有效方法,因为我们现在不希望在此资源上执行任何方法,因此我们无法返回405.
最有可能发生冲突以响应PUT请求。对于 例如,如果正在使用版本控制并且该实体是PUT 包括对资源的更改与资产的更改 早期(第三方)请求,服务器可能会使用409响应 表示无法完成请求。在这种情况下, 响应实体可能包含差异列表 两种版本之间采用响应定义的格式 内容类型。
但是假设URI上已经存在资源(如何与任何东西发生冲突?)。
请求的资源在服务器上不再可用,没有 转发地址是已知的。预计这种情况会发生 被视为永久性具有链接编辑功能的客户端应该 用户批准后删除对Request-URI的引用。如果 服务器不知道,或无法确定,无论是否 条件是永久的,状态代码404(未找到)应该是 用来代替。
这个也很有意义。
我已经编辑了这篇文章几次,当它声称“使用410或404”时它被接受,但现在我认为403也可能适用,因为RFC没有声明403必须是权限相关(但它似乎是由流行的Web服务器实现的)。我想我已经淘汰了所有其他400代码,但随意评论(在你投票之前)。
答案 1 :(得分:0)
你的问题有一个未说明的,假定的前提,必须存在资源才能使PUT成功。这不是一个有效的假设。
规范的相关部分(RFC2616)说:
用户代理知道预期的URI,服务器不得尝试将请求应用于其他资源。
规范没有说,"引用URI的对象必须已经存在,以便PUT成为该URI的成功。"
简单的例子是通过REST实现的Web商店。 GET
返回给定路径上对象的表示,而DELETE
删除给定路径上的项目。这很容易。但POST和PUT并不难理解。 POST
可以执行任何操作,但是POST
的一次使用会在客户端指定的容器中创建一个对象,并让服务器返回该容器中新创建的对象的URI。 PUT
更为有限;它为服务器提供给定URI处对象的表示。该对象可能已经存在,或者可能不存在。 PUT
不是REPLACE的同义词。
在我看来,对于PUT来说409或410是错误的,除非容器本身 - 你试图放入的东西,不存在。
因此:
POST /container
==> returns 200 with `Location:/container/resource-12345`
PUT /container/resource-98928
==> returns 201 CREATED or 200 OK
PUT /this-container-does-not-exist/resource-22828282
--> returns 400
当然,无论您是否希望您的服务器允许这些PUT语义,都取决于您。但是规范中没有任何内容表明您不得允许客户端提供他正在进行PUT的资源的URI。