30

想象一个 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。想法?

4

1 回答 1

21

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

404 未找到

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

409 冲突

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

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

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

于 2012-05-23T21:26:44.527 回答