缺少父资源的REST HTTP响应代码

It'*_*unt 8 rest http httpresponse http-response-codes

我的问题是,当父资源或更高资源不存在/已被删除时,我是否应该返回HTTP响应代码400 Bad Request,404 Not Found或410 Gone?

寻找一些有关如何处理RESTful资源树中缺失链接的指导,因为我已经阅读了很多但没有很多个人经验。

假设我们具有以下资源结构:

/users/{userId}/accounts/{accoundId}/logs/{logId}
Run Code Online (Sandbox Code Playgroud)

一个用户可以拥有多个帐户,而这些帐户又可以具有许多订单,而这些订单又可以具有许多日志。日志仅针对单个帐户存在,而帐户仅针对单个用户存在。没有帐户就不能存在日志,没有用户就不能存在帐户。

当我尝试解决以下问题时,我的问题来了:

/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
Run Code Online (Sandbox Code Playgroud)

但是此资源不存在或不再存在:

/users/123/accounts/321
Run Code Online (Sandbox Code Playgroud)

或此资源不存在或不再存在:

/users/123
Run Code Online (Sandbox Code Playgroud)

我可以说这是一个400 Bad Request,根据RFC7231

6.5.1。400错误的要求

400(错误请求)状态代码表示服务器由于某些原因(例如格式错误的请求语法,无效的请求消息框架或欺骗性的请求路由)而被视为客户端错误,因此服务器无法或不会处理该请求。

从定义上讲是正确的,除非高速缓存尚未过期,这意味着应用程序尚未重新遍历层次结构,而另一个应用程序已删除了父资源。通过提供相关的oplock,客户端将证明,根据其最新知识,它正在发出语义上正确的请求。

本能地会向“ 404 Not Found”或“ 410 Gone”借钱,即使这不是缓存内容,因为失败的原因实际上是缺少/不可用的资源。但是,按照RFC7231规范:

6.5.4。找不到404

404(未找到)状态代码表示原始服务器未找到目标资源的当前表示或不愿意透露该资源的存在。404状态代码不表示这种缺乏表示是暂时的还是
永久的;如果
原始服务器大概通过某种可配置的方式得知该条件很可能是永久性的,则与404相比,首选410(已消失)状态代码。

要么

6.5.9。410去了

410(已消失)状态代码指示在源服务器上不再可以访问目标
资源
,并且这种
情况很可能是永久的。

这些似乎在欺骗本能。

是否有人在处理这种或类似场景和良好方法方面有任何经验?我觉得应该使用正确的感觉,以及使用此服务时应该看到的东西,而不是文字文字。

Voi*_*son 8

要记住的一件事:HTTP响应(包括元数据,包括状态代码)特定于所请求的资源,而不是事物的某些隐式层次结构。

那是说

GET /users/{userId}/accounts/{accoundId}/logs/{logId}
Run Code Online (Sandbox Code Playgroud)

请求:目标资源的当前选定表示形式。参见RFC 7231 ; 特别是,请求不会询问以下任何一种表示形式:

/users/{userId}/accounts/{accoundId}/logs/
/users/{userId}/accounts/{accoundId}/
/users/{userId}
...
Run Code Online (Sandbox Code Playgroud)

比这简单得多-我能满足我的要求吗?并且源服务器提供响应,该响应可以是当前表示,也可以是说明没有此类表示可用的消息。

/users/{userId}/accounts/{accoundId}/logs/{logId}因为/users/{userId}/accounts/{accoundId}不存在,所以没有可用的表示形式是一个实现细节

404通常是您要用作状态代码来宣布目标资源的当前表示不可用的状态。对于这种情况的解释,通常会进入消息正文。例如,您可以使用问题详细信息进行描述。

服务器没有义务仅仅因为资源恰好有一个闲置资源就发送过期的资源表示(同样,缓存是实现细节)。

410几乎同样的事情; 这实际上是一个建议,客户可以将其书签标记为已弃用。

如果找不到在负载中更适合消息语义的状态代码,则400是一种完全合理的方法。但是在这种情况下我404真的不会满足您的需求。