HTTP 404是否是PUT操作的适当响应,其中找不到某些链接资源?

jwl*_*jwl 25 api rest http

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

PUT http://..../api/v1/events/456/attendees/789
Run Code Online (Sandbox Code Playgroud)

如果事件#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... }
Run Code Online (Sandbox Code Playgroud)

如果位置#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,第二个例子不应该返回404.原因在于,在第一种情况下,我们要添加的资源使用事件456和参与者789作为它的复合主键; 第二个案例位置只是一个外键.在第二种情况下,应该返回错误,但不是404 - 可能是412 Precondition Failed或者可能只是400 Bad Request.思考?

And*_*ach 17

有许多4xx HTTP状态代码.最有可能是404或409:

404未找到

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

409冲突

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

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

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

  • @joelarson:它没有说用户应该如何解决冲突。可能是通过发送一封电子邮件,说“请添加位置123”,有关响应的建议也可能包括在内。我想说的是,如果情况是“由于情况Y,您不能做X”,那就是409;如果是“我找不到URI'X'”,则为404。 (2认同)