对于一般不成功的请求(非错误) ,适当的 HTTP状态码响应是什么?

我正在创建一个 RESTful API,它将处理许多用户交互,包括使用存储的信用卡下订单。

在订单成功的情况下,我将返回一个200 OK,在订单请求格式不正确或无效的情况下,我将返回一个400 Bad Request。但是,如果在实际处理订单过程中出现问题,我应该返回什么?

  1. 客户端 POSTS 订单到服务器的用户资源。如果用户不存在,则返回404未找到。
  2. 订单格式和信息已验证。如果无效,将返回400个错误请求。
  3. 订单处理完毕。如果订单成功,则为订单返回一个201Created。如果遇到意外错误,则返回500服务器错误。

最后一步是问题——如果因为其他原因订单没有完成,我应该返回什么?可能的设想包括:

  • 货卖完了
  • 达到用户最大订单限额
  • 信用卡交易失败(资金不足等)

这看起来不太适合400或500分。如果没有更好的代码,我可以把它看作400——根据业务规则,请求是无效的。只是看起来不太准确。

编辑: 也找到了相同主题的 现有的讨论。所有的答案似乎都指向对这种类型的违规使用状态代码,在使用400、409或422扩展之间进行了一些讨论。

78287 次浏览

业务规则应该使用400。如果订单不被接受,不要返回2xx。HTTP 是一个应用程序协议,永远不要忘记这一点。如果返回2xx,客户端就可以假定订单已被接受,而不管您在正文中发送了什么信息。


来自 RESTful Web 服务食谱:

一些 Web 服务常犯的一个错误是返回一个状态 反映成功的代码(状态代码从200到206和从300 到307) ,但包含描述错误条件的消息正文。 这样做可以防止感知 HTTP 的软件检测错误 例如,缓存将把它存储为成功响应,并将它提供给 即使后来的客户能够成功地 请求。

我将让您在4xx 和5xx 之间做出选择,但是您应该使用错误状态代码。

如果客户端可以修改请求以避免错误,那么应该使用4xx 来处理客户端错误。对于客户端无法解决的服务器错误,使用5xx。

产品售罄将是一个服务器错误。客户机无法以某种方式修改请求以避免出现错误。你可以转换到其他产品,但这不是一个新的要求吗?

达到的用户最大订单限制也是服务器错误。客户端无法解决这个错误。

信用卡交易失败将是客户端错误。客户端可以使用不同的支付方法或信用卡号重新提交请求,以解决错误。

我不认为400可以用于所有的业务场景。它可用于基本数据输入验证。除此之外,我们可能很难在此错误代码中安装其他业务逻辑。由此处理的错误大多是开发人员在客户机编码期间可能遇到的设计时错误。

假设所有参数都是正确的,假设我们将用户帐号传递到请求中。

所以请求现在不再是一个不好的请求,服务器能够接受请求。但是现在它拒绝根据现有的新资料满足要求,因为账户没有足够的余额。

我建议在这些场景中使用带有适当错误消息的403。

其他可能的错误代码可能是409冲突。但是,在资源处于一致状态的情况下,可以使用这种方法。

我知道这个问题很老了,但我今天想到了同样的问题。如果我的用户用完了积分,我的 REST API 应该返回什么状态代码?

我倾向于 402 Payment Required:

根据 维基百科:

留着以后用。最初的意图是,这个代码可能被用作某种形式的数字现金或小额支付计划的一部分,但这并没有发生,这个代码通常不被使用。如果某个特定开发人员的请求超过了每日限制,GoogleDevelopersAPI 将使用此状态。

事实上 是的:

付款 _ 必须(402)

  • 开发商设定的每日预算限额已经达到。
  • 请求的操作所需的资源超过配额允许的数量。完成操作需要付款。
  • 请求的操作需要经过身份验证的用户支付某种类型的费用。

错误类型:

4×× Client Error

错误代码:

422 Unprocessable Entity

服务器理解请求实体的内容类型(因此415 Unsupport Media Type status code 是不合适的) ,请求实体的语法是正确的(因此400 Bad Request status code 是不合适的) ,但是无法处理所包含的指令。

例如,如果 XML 请求体包含格式良好(即语法正确)但语义错误的 XML 指令,则可能发生此错误条件。

Https://httpstatuses.com/422

我选406Not Acceptable

下面是一个4xx 的列表:

const HTTP_BAD_REQUEST = 400;
const HTTP_UNAUTHORIZED = 401;
const HTTP_PAYMENT_REQUIRED = 402;
const HTTP_FORBIDDEN = 403;
const HTTP_NOT_FOUND = 404;
const HTTP_METHOD_NOT_ALLOWED = 405;
const HTTP_NOT_ACCEPTABLE = 406;
const HTTP_PROXY_AUTHENTICATION_REQUIRED = 407;
const HTTP_REQUEST_TIMEOUT = 408;
const HTTP_CONFLICT = 409;
const HTTP_GONE = 410;
const HTTP_LENGTH_REQUIRED = 411;
const HTTP_PRECONDITION_FAILED = 412;
const HTTP_REQUEST_ENTITY_TOO_LARGE = 413;
const HTTP_REQUEST_URI_TOO_LONG = 414;
const HTTP_UNSUPPORTED_MEDIA_TYPE = 415;
const HTTP_REQUESTED_RANGE_NOT_SATISFIABLE = 416;
const HTTP_EXPECTATION_FAILED = 417;
const HTTP_I_AM_A_TEAPOT = 418;                                               // RFC2324
const HTTP_MISDIRECTED_REQUEST = 421;                                         // RFC7540
const HTTP_UNPROCESSABLE_ENTITY = 422;                                        // RFC4918
const HTTP_LOCKED = 423;                                                      // RFC4918
const HTTP_FAILED_DEPENDENCY = 424;                                           // RFC4918
const HTTP_RESERVED_FOR_WEBDAV_ADVANCED_COLLECTIONS_EXPIRED_PROPOSAL = 425;   // RFC2817
const HTTP_UPGRADE_REQUIRED = 426;                                            // RFC2817
const HTTP_PRECONDITION_REQUIRED = 428;                                       // RFC6585
const HTTP_TOO_MANY_REQUESTS = 429;                                           // RFC6585

424 Failed Dependency怎么样? 说明书将其描述为:

该方法无法在资源上执行,因为请求的操作依赖于另一个操作,而该操作失败。

但也有 这个定义:

状态代码424是在 WebDAV 标准中定义的,用于客户端需要更改其正在执行的操作的情况——服务器在这里没有遇到任何问题。

你可以告诉客户(或者假装)你有一些内部操作,这些操作应该创建订单,然后扣除余额,其中一个操作失败了,尽管是出于完全合理的原因,这就是请求失败的原因。

据我所知,“行动”是一个相当宽泛的术语,可用于各种情况,包括库存不足,信用不足,或仓库晚会。


另一个选择可能是 422 Unprocessable Entity:

服务器理解请求实体的内容类型(因此415 Unsupport Media Type status code 是不合适的) ,请求实体的语法是正确的(因此400 Bad Request status code 是不合适的) ,但是无法处理所包含的指令。

例如,如果 XML 请求体包含格式良好(即语法正确)但语义错误的 XML 指令,则可能发生此错误条件。

试图请求一个缺货的项目,或者当您没有足够的信用时,可能会被认为是语义层面的错误。

MozDev 指出了客户端的一个错误,特别是: 客户端不应该在没有修改的情况下重复此请求。

输入验证失败时的环回4 用途422。


可以说,库存不足或仓库聚会之夜可以被视为临时状态,因此稍后可以重试该请求。这种情况可以由 503 Service Unavailable表示

由于临时过载或预定维护,服务器当前无法处理请求,这可能会在一些延迟后得到缓解。

服务器可能会发送一个 Retry-After 头字段,建议客户端在重试请求之前等待适当的时间。