我的问题是,当父资源或更高资源不存在/已被删除时,我应该返回400 Bad Request,404 Not Found或410 Gone的HTTP响应代码吗?
寻找有关如何处理RESTful资源树中缺少链接的一些指导,因为我已经阅读了相当多但不是很多个人经验。
假设我们有以下资源结构:
/users/{userId}/accounts/{accoundId}/logs/{logId}
一个用户可以拥有多个帐户,而这些帐户又可以拥有多个订单,而这些订单又可以包含许多日志。日志仅针对单个帐户存在,而帐户仅针对单个用户存在。没有帐户就不能存在日志,没有用户就无法存在帐户。
当我尝试解决以下问题时,我的问题出现了:
/users/123/accounts/321/logs - POST
/users/123/accounts/321/logs/987 - GET
/users/123/accounts/321/logs/987 - PUT
/users/123/accounts/321/logs/987 - DELETE
/users/123/accounts/321/logs/987 - PATCH
/users/123/accounts/321/logs/987 - HEAD
但是这种资源不存在或不存在:
/users/123/accounts/321
或此资源不存在或不存在:
/users/123
我认为这是一个 400错误请求,根据RFC7231:
6.5.1。 400错误请求
400(错误请求)状态代码表示服务器不能 或者由于感知到的东西而不会处理请求 是客户端错误(例如,格式错误的请求语法,无效 请求消息框架或欺骗性请求路由)。
定义为true,除非在缓存未过期的情况下,意味着应用程序尚未重新遍历层次结构,另一个应用程序已删除父资源。通过提供相关的oplock,客户端将证明,根据其最后的知识,它正在做出语义上正确的请求。
本能地 会借助 404 Not Found 或 410 Gone ,即使这不是缓存的事情,因为失败的原因实际上是一个缺失/不可用的资源。但是根据规范RFC7231:
6.5.4。找不到404
404(未找到)状态代码表示原始服务器 没有找到目标资源的当前代表或是 不愿意透露那个存在。 404状态代码 不表明这种缺乏代表性是暂时的还是暂时的 常驻;如果是,则410(Gone)状态代码优先于404 原始服务器可能通过一些可配置的方式知道 这种情况可能是永久性的。
或
6.5.9。 410 Gone
410(Gone)状态代码表示访问目标
资源在原始服务器上不再可用,而且这个 条件可能是永久性的。
这似乎可以说明这种本能。
有没有人有过处理这种或类似场景和好方法的经验?我觉得我应该选择感觉正确的东西以及我希望看到的消费服务,而不是文字。
答案 0 :(得分:5)
要记住的一点是:HTTP响应(包括包含状态代码的元数据)特定于请求的资源,而不是某些隐式的层次结构。
这就是说
GET /users/{userId}/accounts/{accoundId}/logs/{logId}
请求:目标资源的当前选定表示。见RFC 7231;特别是,请求并不询问任何这些的表示:
/users/{userId}/accounts/{accoundId}/logs/
/users/{userId}/accounts/{accoundId}/
/users/{userId}
...
它比那简单得多 - 我能得到我要求的东西吗?并且原始服务器提供响应,该响应可以是当前表示,或者它可以是解释没有这样的表示可用的消息。
由于/users/{userId}/accounts/{accoundId}/logs/{logId}
不存在而无法使用/users/{userId}/accounts/{accoundId}
的表示,因此实施细节。
404通常是您希望用作状态代码以宣布目标资源的当前表示不可用的内容。对于为什么会出现这种情况的任何解释通常都会进入消息体。例如,您可以使用problem details来描述它。
服务器没有义务发送资源的过期表示,只是因为它碰巧有一个(再次,缓存是一个实现细节)。
410 几乎同样的事情;它实际上是一个顾问,客户可以将其书签标记为已弃用。
如果您无法找到更符合有效负载中消息语义的状态代码,那么 400是一种非常合理的方式。但是,如果404
确实符合您的需求,我就不会使用。
答案 1 :(得分:1)
否:排除 400错误请求,因为您提到的所有请求都有效。
否:添加一些香料:我在类似的情况下看到了 409 Conflict 。在您的情况下,这似乎是不合适的,因为您清楚地表明资源缺失。
是:如果您的资源不存在, 404 Not Found 是最合适的响应。它是否存在无关紧要。 404表示“抱歉,资源不可用”。我会添加一条错误消息,准确地说明缺少资源,以便您的API消费者能够更好地处理这种情况。
可能: 410 Gone 是404的特定情况。如果资源不可用并且它之前存在,则应该引发它和它(实际上)将再也不存在。因此,无论您多久以及何时尝试获取资源,您都将永远不会再获得它,但在过去,您可能已经能够获得它。同样的事情:如果您决定使用410,请考虑添加精确的错误消息。
个人说明:
答案 2 :(得分:-2)
410 Gone
如果/ users / 123 / accounts / 321 / logs / 987不再存在,则410 Gone是最合适的响应。由于/ users / 123被删除而删除的事实与/ users / 123 / accounts / 321 / logs / 987的请求无关。
400 Bad Request对于/ users / 123 / accounts / 321 / lergs / 987的请求更合适。