对于未找到某些链接资源的 PUT 操作,HTTP 404 是不是是适当的响应? [关闭]

Posted

技术标签:

【中文标题】对于未找到某些链接资源的 PUT 操作,HTTP 404 是不是是适当的响应? [关闭]【英文标题】:Is HTTP 404 an appropriate response for a PUT operation where some linked resource is not found? [closed]对于未找到某些链接资源的 PUT 操作,HTTP 404 是否是适当的响应? [关闭] 【发布时间】:2012-05-30 11:01:13 【问题描述】:

想象一个 REST Web 服务,您在其中将项目添加到某种类型的容器中。例如,假设我们可以将参与者 #789 添加到事件 #456,如下所示:

PUT http://..../api/v1/events/456/attendees/789

如果事件 #456 或与会者 #789 不存在,返回 HTTP 404 是否正确(以及解释问题所在的详细错误负载,例如 "error" : "message" : "Event 456 does not exist" , "code" : "404"

同样,如果我正在创建引用另一个对象的新对象,但另一个对象不存在怎么办?例如,假设我正在位置 #123 创建一个事件

PUT http://..../api/v1/event
 "location": 123, "name": "Party", "date": "2012-05-23", ...etc... 

如果位置 #123 不存在,返回 404(连同响应的详细信息)是否也正确?如果不是,什么是合适的 - 只是 400?

根据 HTTP 1.1 规范http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html

9.6 PUT ...如果无法使用 Request-URI 创建或修改资源,则应给出反映问题性质的适当错误响应

因此,用 404 响应似乎是一个不错的投票。但是由于某种原因我不能完全确定,用 404 响应 PUT(或 POST)似乎很奇怪对我来说……也许是因为404意味着找不到资源,但是在这种情况下,我们的资源实际上是两个其他资源之间的链接,并且是这两个无法找到的资源之一。

不要太担心我在这里的确切例子——它们是为了说明这一点而编造的。主要问题是:404 是对因未找到链接资源而失败的 PUT 操作的适当响应吗?

如果您能指出参考资料,那就太好了——我很难找到任何涉及这种详细程度且足够可信的资料。尤其是关于 REST API 设计中资源关系的处理。

更新思路我认为第一个示例可能应该返回 404,第二个不应该。理由是,在第一种情况下,我们添加的资源使用事件 456 和参加者 789 作为复合主键;第二种情况位置只是一个外键。在第二种情况下,应该返回一个错误,但不是 404——可能是 412 Precondition Failed 或者可能只是 400 Bad Request。想法?

【问题讨论】:

恕我直言,从客户端的角度来看,您从根 (/) 开始并沿着路径前进。如果在任何时候找不到某个路径部分,您应该急切地抛出 404。如果您能提供实际失败的部分会很好,但我发现 404 是合理的。 【参考方案1】:

有多个 4xx HTTP status codes。最有可能的是 404 或 409:

404 未找到

服务器未找到任何与有效请求 URI 匹配的内容。 没有说明这种情况是暂时的还是 永恒的。如果服务器应该使用 410 (Gone) 状态码 通过一些内部可配置的机制知道,一个旧的 资源永久不可用且没有转发地址。 当服务器不希望这样做时,通常使用此状态码 准确说明请求被拒绝的原因,或者当没有其他请求时 响应是适用的。

409 冲突

由于与当前的冲突,请求无法完成 资源的状态。仅在以下情况下才允许使用此代码 预计用户可能能够解决冲突 并重新提交请求。响应正文应该包含足够的 供用户识别冲突来源的信息。 理想情况下,响应表示将包含足够的信息 供用户或用户代理解决问题;然而,这可能 不可能,也不是必需的。

在响应 PUT 请求时最有可能发生冲突。为了 例如,如果正在使用版本控制并且表示是 PUT 包括对资源的更改,这些更改与由 较早的(第三方)请求,服务器可能使用 409 response 表示它无法完成请求。在这 在这种情况下,响应表示可能包含一个列表 两个版本的区别。

其中任何一个都适合,但我想我会选择 409。404 用于 URI not found 但 409 表示资源的当前状态不允许请求的操作.在您的情况下,请求无法得到满足,因为有些事情不允许这样做。

【讨论】:

409 是一个可能的选择。关于“用户可能能够解决冲突并重新提交请求”的部分是一个有趣的皱纹。以我为例,如果位置无法通过 API 添加,或者由于用户的安全级别而可能无法由用户添加——409 是否仍然有效?如果我们为该类型的错误返回 404 并为用户可以使用 API 添加缺失项的其他几乎相同的错误返回 409,这是否会令人困惑? ... 尽管如此,409 可能没有意义,因为用户可能无法创建一个 id#123 的位置,假设它是一个自动分配的键... @joelarson:它没有说如何用户应该解决冲突。可能是通过发送一封电子邮件说“请添加位置 123”,并且可能会在回复中包含有关如何执行此操作的建议。我会争辩说,如果情况是“由于情况 Y,你不能做 X”,那么它就是 409;如果是“我找不到 URI 'X'”,那么它就是 404。

以上是关于对于未找到某些链接资源的 PUT 操作,HTTP 404 是不是是适当的响应? [关闭]的主要内容,如果未能解决你的问题,请参考以下文章

API 设计:移除未使用的 CRUD 服务

抽象的通用 ODataController 类导致“未找到 HTTP 资源”

是否允许使用 409 Conflict 状态码来防止在 HTTP PUT 请求中更新某些字段

HTTP接口请求

未找到搜索结果的正确 HTTP 状态代码是啥?

HTTP常用状代码