Api 对于找不到链接资源的PUT操作,HTTP 404是合适的响应吗?

Api 对于找不到链接资源的PUT操作,HTTP 404是合适的响应吗?,api,http,rest,Api,Http,Rest,想象一下一个REST Web服务,您正在其中向某种类型的容器添加项。例如,假设我们可以将与会者789添加到活动456中,如下所示: PUT http://..../api/v1/events/456/attendees/789 如果event#456或attendee#789不存在,返回HTTP 404(以及解释问题的详细错误负载,例如{“error”:{“message”:“event 456不存在”,“code”:“404”},是否正确 类似地,如果我正在创建引用另一个对象的新对象,但另一

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

PUT http://..../api/v1/events/456/attendees/789
如果event#456或attendee#789不存在,返回HTTP 404(以及解释问题的详细错误负载,例如
{“error”:{“message”:“event 456不存在”,“code”:“404”}
,是否正确

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

如果位置#123不存在,返回404(以及响应中的详细信息)是否也正确?如果不存在,什么才是合适的——仅返回400

根据HTTP 1.1规范

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

所以这似乎是对404的一个很好的投票。但是由于某些原因,我不能完全把我的手指放在上面,对put(或POST)做出回应使用404对我来说似乎很奇怪……可能是因为404意味着无法找到资源,但在本例中,我们的资源实际上是两个其他资源之间的链接,而它是无法找到的两个资源之一

不要太担心我这里的确切例子——它们是用来说明这一点的。主要问题是:404是对由于找不到链接资源而失败的PUT操作的适当响应吗

如果您可以指向引用,那就太好了--我很难找到任何能够深入到这种详细程度并且足够可信的引用,特别是在RESTAPI设计中处理资源关系方面

更新思考我认为第一个示例可能应该返回404,第二个不应该返回404。原因是,在第一种情况下,我们添加的资源使用事件456和与会者789作为复合主键;第二种情况下的位置只是外键。在第二种情况下,应该返回错误ned,但不是404——可能是412先决条件失败,也可能只是400个错误请求。想法?

有很多4xx。最有可能是404或409:

404未找到

服务器未找到任何与有效请求URI匹配的内容。 没有说明该情况是暂时的还是暂时的 永久性。如果服务器 通过一些内部可配置的机制知道 资源永久不可用且没有转发地址。 当服务器不希望更改时,通常使用此状态代码 明确说明请求被拒绝的原因,或者没有其他原因 答复是适用的

409冲突

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

在响应PUT请求时最有可能发生冲突。对于 例如,如果正在使用版本控制,并且正在使用表示 将包含的更改放在与所做更改冲突的资源上 如果是早期(第三方)请求,服务器可能会使用409 响应以指示它无法完成请求。在此 在这种情况下,响应表示可能包含 两个版本之间的差异


这两种方法都是合适的,但我想我会选择409。404用于找不到URI,但409表示资源的当前状态不允许请求的操作。在您的情况下,请求无法满足,因为存在不允许的问题。

IMHO从客户端角度看,您是从根开始的(
/
)并沿着路径走。如果在任何一点上找不到某个路径部分,您都应该急切地抛出404。如果您能够提供实际失败的部分,那将是很好的,但我认为404是合理的。409是一个可能的选择。关于“用户可能能够解决冲突并重新提交请求”的部分这是一个有趣的问题。以我为例,如果由于安全级别的原因,无法通过API添加位置,或者用户可能无法添加位置——409仍然有效吗?如果我们返回404表示该类型的错误,返回409表示用户可以使用API添加缺少的项的其他几乎相同的错误,这会令人困惑吗?…仍然是409 m可能没有意义,因为用户可能无法创建id为#123的位置,假设它是自动分配的密钥…@joelarson:它没有说明用户应该如何解决冲突。可能是通过发送电子邮件说“请添加位置123”我认为,如果情况是“因为情况Y而不能执行X”,那么它是409;如果是“我找不到URI‘X’”,那么它是404。
PUT http://..../api/v1/event
{ "location": 123, "name": "Party", "date": "2012-05-23", ...etc... }