如果资源不可用于请求的操作,HTTP 状态代码应该是啥?

Posted

技术标签:

【中文标题】如果资源不可用于请求的操作,HTTP 状态代码应该是啥?【英文标题】:what should be HTTP status code if resource is not available for requested action?如果资源不可用于请求的操作,HTTP 状态代码应该是什么? 【发布时间】:2014-12-03 13:28:53 【问题描述】:

我正在开发一个 RESTful API。我对在这种特定情况下设置 HTTP 状态代码感到困惑。我不确定我(服务器)应该返回什么状态码。

假设我的应用程序具有关注用户功能,如果我已经关注用户并且我再次发送相同用户 ID 的关注请求,那么在这种情况下应该是来自服务器的 HTTP 状态代码。状态代码后面会出现一条错误消息,例如:“已经关注用户”。

类似的场景可以考虑取消关注用户功能,如果我没有关注用户“A”,我仍然向取消关注用户“A”发送请求,那么服务器应该返回什么 HTTP 状态代码并带有类似“不”的错误消息关注用户取消关注”

当然 200 响应代码在这里似乎不适合我?是吗?

如果我在错误的堆栈交换站点上发布了问题,请原谅我,我将其发布在 *** 站点上只是因为它与 REST API 相关。

编辑

从客户端用户需要向 URL 发送 POST 请求:

http://www.myserver.com/api/follow/10

以及其他必要的参数(如 API 密钥、正确的标头等),用于在服务器端处理请求之前进行身份验证。

取消关注的类似网址是:

http://www.myserver.com/api/unfollow/10

现在,如果客户端发送关注请求,我将发送 HTTP 状态代码 200 作为响应,例如,对于用户 id 10,即使他/她已经在关注 id 为 10 的用户。在这种情况下,连同状态代码(200)我正在发送类似于“已经关注用户”的消息

不知何故,我觉得这并不令人信服,因为没有创建/更新任何资源,它应该返回带有正确状态代码的错误消息,而不是 200,可能来自 4XX,不确定。

【问题讨论】:

能否请您添加有关如何发送这些“关注”和“取消关注”请求的信息?因为听起来您在 URI 中使用了动词,这不会很 RESTful。 @Robert 我已经用有关关注/取消关注 URI 的信息更新了问题 【参考方案1】:

422 无法处理的实体

422 似乎是此用例中正确的 HTTP 状态代码。 422的描述说:

422(Unprocessable Entity)状态码意味着服务器理解请求实体的内容类型(因此415(Unsupported Media Type)状态码是不合适的),并且请求实体的语法是正确的(因此 400(错误请求)状态代码不合适)但无法处理包含的指令。

【讨论】:

根据相关问题接受了这个答案:***.com/a/9382163/974616【参考方案2】:

答案取决于您的 API。您用“关注用户 X”或“取消关注用户 Y”来描述 API。这让我觉得您可能正在以 RPC 风格来处理您的 API 设计,而不是专注于资源。

如果您的 API 使用包含 HATEOAS 原则的 REST,则 4xx 范围内的错误代码可能是合适的(但在这种情况下我建议不要这样做,见下文)。简而言之:HATEOAS 意味着您的资源提供了指向可能的“行动”的链接。你可以在这里阅读更多信息:http://restcookbook.com/Basics/hateoas/

除此之外,将您的 API 设计为“容错”似乎是个好主意,即期望多次发送相同的请求(例如,因为用户不耐烦并且一次又一次地单击,或者浏览器崩溃并重新启动并重新打开所有以前的标签,或...)。

我的个人意见和建议如下:

关注用户 X:您的实现应该检查是否需要添加新的关注者。不管用户是否已经关注,发回 HTTP 状态 201(已创建)并添加指向资源的“Location”HTTP 标头。 取消关注用户 X:您的实现应该检查是否需要删除关注者。不管用户是否已经从关注者中删除,发回 HTTP 状态 200(OK)。

一般的想法是,如果客户端以某种方式请求某事并且已经是这种情况,那么服务器有两个选择:要么它响应客户端“您希望的结果已经到位。因此您的请求是无效的。”或者服务器可以响应“您希望的结果已经到位。您拥有所需的一切。”。 选择第二个选项使 API 更加宽容并有助于幂等性(请参阅 http://restcookbook.com/HTTP%20Methods/idempotency/)。

【讨论】:

感谢您的评论,我会等待一段时间,然后将您的答案作为“已接受”的答案接受,只是为了确认。至于是否针对 4XX 代码发送 200/201 是我的主要困惑【参考方案3】:

我认为 djlauk 的回答涵盖了很多,但我想给出一些不同的方法并添加一些信息:

不要在 URI 中使用动词

我不会在 /follow//unfollow/ URI 上使用 POST,因为这不是很 RESTful 请参阅这个 SO 问题:Why does including an action verb in the URI in a REST implementation violate the protocol? 尤其是这个 SO 答案:How to create REST URLs without verbs?

对动作使用正确的 HTTP 动词

您要做的是创建一个实体(“关注”),以便您可以使用 HTTP 动词 POST 或 PUT,然后删除该实体(“取消关注”),其中 @987654325 @ 将是合适的选择。

我的 API 方法:

我会做以下事情:

(前两个例子只是为了解释结构,不需要就不用实现。)


这确实让您成为用户“罗伯特”:

GET http://www.myserver.com/api/users/robert/

回复:#200


这确实让您知道用户“罗伯特”正在关注:

GET http://www.myserver.com/api/users/robert/following/

回复:#200


这就是让“robert”跟随“rahul”的方式:

PUT http://www.myserver.com/api/users/robert/following/rahul

回复:#200

如果您再次发送此请求,您会得到相同的响应:#200 因为 PUT 是幂等的,这就是它应该表现的方式(参见 (2))


当你现在想让“robert”取消关注“rahul”时:

DELETE http://www.myserver.com/api/users/robert/following/rahul

回复:#200

如果您再次发送 DELETE 请求,您会得到一个稍微不同的响应 #404,但这是 HTTP 标准,客户端应该理解这一点。


对于HTTP方法的常规答案代码我也可以推荐这个来源:restapitutorial.com

【讨论】:

【参考方案4】:

我会使用以下一些:

System.Net.HttpStatusCode.ServiceUnavailable;
System.Net.HttpStatusCode.MethodNotAllowed;
System.Net.HttpStatusCode.BadRequest;

最好是前两个之一。

【讨论】:

【参考方案5】:

当然 200 响应代码在这种情况下不起作用。

以下是 HTTP 状态代码中的组:

1xx 信息性 2xx 成功 3xx 重定向 4xx 客户端错误 5xx 服务器错误

当然你需要使用 4xx。

我认为对于您在此处描述的情况,您可以使用以下任何一种:

405 方法不允许

使用该资源不支持的请求方法对该资源发出请求;例如,在需要通过 POST 呈现数据的表单上使用 GET,或者在只读资源上使用 PUT。

400 错误请求

由于被认为是客户端错误,服务器无法或不会处理请求

409 冲突

表示由于请求中的冲突而无法处理请求,例如多次更新时的编辑冲突。

更多详情请点击此处: http://en.wikipedia.org/wiki/List_of_HTTP_status_codes

【讨论】:

405 - 不允许的方法:我认为它在这里不适用,因为方法在那里可用并且还以正确的格式发送参数 400 - 恕我直言,这也不适用“错误请求”意味着请求不能被服务器理解,这里不是这种情况 409-冲突状态可能在这里适用

以上是关于如果资源不可用于请求的操作,HTTP 状态代码应该是啥?的主要内容,如果未能解决你的问题,请参考以下文章

有效负载中指定的无效资源的 HTTP 状态代码

对已禁用资源的操作的预期 HTTP 状态代码

HTTP状态码

HTTP状态码

http协议的状态码

HTTP状态代码含义