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

我正在创build一个RESTful API来处理一些用户交互,包括使用存储的信用卡下订单。

在订单成功的情况下,我将返回200 OK,如果订单请求格式错误或无效,我将返回400错误请求。 但是,如果在订单的实际处理过程中出现问题,我该怎么办?

  1. 客户端POSTS命令为服务器用户资源。 如果用户不存在,则返回404 Not Found。
  2. 订单格式和信息经过validation。 如果无效,则返回400错误请求。
  3. 订单已处理。 如果订单成功,则会为订单返回201 Created。 如果遇到意外错误,则返回500服务器错误。

最后一步是问题 – 如果订单因其他原因没有完成,我将返回什么? 可能的情况可能包括:

  • 产品售罄
  • 已达到用户最高订单限制
  • 信用卡交易失败(资金不足等)

这似乎并不适合400或500.如果没有更好的代码,我可以看到它是400,根据业务规则,请求无效。 这似乎并不准确。

编辑:也发现了同样的话题这个现有的讨论 。 所有的答案似乎都指出了使用状态代码来处理这种违规行为,在使用400,409或422扩展之间进行了一些讨论。

您应该使用400作为业务规则。 如果订单不被接受,则不要退回2xx。 HTTP是一个应用程序协议,永远不会忘记。 如果您返回2xx,客户可以假定订单已被接受,而不pipe您在正文中发送的任何信息。


从REST风格的Web服务食谱 :

一些Web服务所犯的一个常见错误是返回反映成功的状态代码(状态代码从200到206,从300到307),但是包含描述错误状态的消息主体。 这样做会阻止HTTP感知软件检测错误。 例如,caching会将其存储为成功响应,并将其提供给后续客户端,即使客户端可能能够发出成功的请求。

我会留给你决定4xx和5xx之间,但你应该使用错误状态代码。

如果客户端可以修改请求以避开错误,则应该使用4xx作为客户端错误。 使用5xx作为客户端无法真正解决的服务器错误。

售完产品将是一个服务器错误。 客户端无法以某种方式修改请求来解决错误。 你可以切换到另一个产品,但不会是一个新的要求?

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

信用卡交易失败将是一个客户端错误。 客户可以使用不同的付款方式或信用卡号码重新提交请求来解决错误。

错误types:

4×× Client Error 

错误代码:

 422 Unprocessable Entity 

服务器理解请求实体的内容types(因此415不支持的媒体types状态码是不合适的),并且请求实体的语法是正确的(因此400错误请求状态码是不恰当的),但是不能处理包含说明。

例如,如果XML请求主体包含格式正确(即,语法正确),但语义错误的XML指令,则可能会出现此错误情况。

https://httpstatuses.com/422

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

我倾向于倾向于402 Payment Required

根据维基百科 :

保留以供将来使用。 最初的意图是这个代码可能被用作某种forms的数字现金或微支付scheme的一部分,但是这没有发生,而且这个代码通常不被使用。 如果某个开发人员的请求超出了每日限制,则Google Developers API会使用此状态。

他们的确的确如此 :

PAYMENT_REQUIRED(402)

  • 已达到开发人员设置的每日预算限制。
  • 请求的操作需要比配额允许的更多的资源。 需要付款才能完成操作。
  • 所请求的操作需要来自经过validation的用户的某种付款。

我去与406 Not 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 

我不认为400可以用于所有的业务场景。 它可以用于基本的数据inputvalidation。 除此之外,我们可能很难适应其他业务逻辑到这个错误代码。 由此处理的错误主要是开发人员在客户端编码期间可能遇到的devise时间错误。

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

所以请求现在不再是一个错误的请求,服务器能够接受请求。 但是现在它拒绝根据可用的新信息填写请求,这是因为帐户没有足够的余额。

我build议我们应该在这些情况下使用403并input适当的错误信息。

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