如果资源不可用于请求的操作,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 状态代码应该是啥?的主要内容,如果未能解决你的问题,请参考以下文章