什么是REST API错误处理最佳实践?

当涉及到REST API的返回错误时,我正在寻找关于良好实践的指导。我正在开发一个新的API,所以我现在可以把它带到任何方向。目前我的内容类型是XML,但我计划将来支持JSON。

我现在添加了一些错误案例,比如客户端试图添加一个新资源,但已经超过了他的存储配额。我已经在处理HTTP状态码的某些错误情况(401用于身份验证,403用于授权,404用于普通的坏请求uri)。我查看了HTTP错误代码,但在400-417范围内似乎没有一个正确地报告应用程序特定的错误。因此,一开始我想用200 OK和一个特定的XML有效负载(即。付我们更多的钱,你就能得到你需要的存储空间!)但我停下来想了想,这似乎有点像肥皂(/惊恐地耸耸肩)。此外,感觉我把错误响应分成不同的情况,因为一些是http状态代码驱动的,另一些是内容驱动的。

那么行业建议是什么呢?好的实践(请解释为什么!),并且,从客户端角度来看,REST API中什么样的错误处理可以使客户端代码更容易?

301777 次浏览

因此,一开始我想用200 OK和一个特定的XML有效负载(即。付我们更多的钱,你就能得到你需要的存储空间!)但我停下来想了想,这似乎有点像肥皂(/惊恐地耸耸肩)。

我不会返回200,除非这个请求真的没有问题。从RFC2616开始,200表示“请求已经成功”。

如果客户端的存储配额已经超出(无论出于什么原因),我将返回403 (Forbidden):

服务器理解请求,但拒绝执行。授权没有帮助,请求不应该重复。如果请求方法不是HEAD,并且服务器希望公开请求没有被完成的原因,它应该在实体中描述拒绝的原因。如果服务器不希望将此信息提供给客户机,则可以使用状态代码404 (not Found)。

这将告诉客户端请求是OK的,但是它失败了(200不会这样做)。这也使您有机会在响应体中解释问题(及其解决方案)。

你想到的其他具体错误情况是什么?

主要的选择是是否将HTTP状态代码作为REST API的一部分。

这两种方法都很有效。我同意,严格地说,REST的思想之一是您应该将HTTP状态代码用作API的一部分(成功操作返回200或201,根据不同的错误情况返回4xx或5xx)。但是,没有REST警察。你可以做你想做的。我曾见过更过分的非rest api被称为“RESTful”。

此时此刻(2015年8月)我建议你使用HTTP状态代码作为你的API的一部分。在使用框架时,现在比过去更容易看到返回代码。特别是,现在比过去更容易看到非200返回的情况和非200响应的主体。

HTTP状态代码是api的一部分

  1. 您需要仔细挑选符合错误条件的4xx代码。您可以将rest消息、xml消息或明文消息作为包含子代码和描述性注释的有效负载。

  2. 客户端需要使用一个软件框架来获取http级别的状态码。通常是可行的,不总是直截了当的。

  3. 客户端必须区分HTTP状态代码(指示通信错误)和您自己的状态代码(指示应用程序级问题)。

HTTP状态代码不是api的一部分

  1. 如果你的应用程序收到请求,然后响应(成功和错误的情况下),HTTP状态代码将始终是200

  2. 你所有的回答都应该包括“信封”或“标题”信息。通常是这样的:

    envelope_ver: 1.0
    status:  # use any codes you like. Reserve a code for success.
    msg: "ok" # A human string that reflects the code. Useful for debugging.
    data: ...  # The data of the response, if any.
  3. This method can be easier for clients since the status for the response is always in the same place (no sub-codes needed), no limits on the codes, no need to fetch the HTTP-level status-code.

Here's a post with a similar idea: http://yuiblog.com/blog/2008/10/15/datatable-260-part-one/

Main issues:

  1. Be sure to include version numbers so you can later change the semantics of the api if needed.

  2. Document...

记住,这里有比HTTP/1.1 rfc中定义的更多的状态码,IANA注册表位于http://www.iana.org/assignments/http-status-codes。就你提到的情况来说状态码507听起来不错。

有两种错误。应用程序错误和HTTP错误。HTTP错误只是为了让AJAX处理程序知道一切正常,不应该用于其他任何事情。

5xx服务器错误

500 Internal Server Error
501 Not Implemented
502 Bad Gateway
503 Service Unavailable
504 Gateway Timeout
505 HTTP Version Not Supported
506 Variant Also Negotiates (RFC 2295 )
507 Insufficient Storage (WebDAV) (RFC 4918 )
509 Bandwidth Limit Exceeded (Apache bw/limited extension)
510 Not Extended (RFC 2774 )

2 xx成功

200 OK
201 Created
202 Accepted
203 Non-Authoritative Information (since HTTP/1.1)
204 No Content
205 Reset Content
206 Partial Content
207 Multi-Status (WebDAV)

然而,如何设计应用程序错误实际上取决于您自己。例如Stack Overflow会发送一个带有responsedatamessage属性的对象。我认为响应包含truefalse,以指示操作是否成功(通常用于写操作)。数据包含有效负载(通常用于读取操作),消息包含任何额外的元数据或有用消息(例如responsefalse时的错误消息)。

不要忘记5xx错误以及应用程序错误。

在这种情况下,409(冲突)怎么样?这假设用户可以通过删除存储资源来解决问题。

否则507(不完全标准)也可以工作。我不会用200,除非你一般用200来表示错误。

正如其他人指出的那样,在错误代码中包含响应实体是完全允许的。

请记住,5xx错误是服务器端错误,也就是说客户端不能更改其请求的任何内容以使请求通过。如果超出了客户端的配额,那肯定不是服务器错误,所以应该避免5xx。

如果超出客户端配额,则是服务器错误,在本例中请避免5xx。

在现有的“最佳实践”上建模你的api可能是正确的方法。 例如,Twitter是如何处理错误代码的 # EYZ0 < / p >

同意了。REST的基本理念是使用web基础设施。HTTP状态代码是消息传递框架,允许各方在不增加HTTP有效负载的情况下相互通信。它们已经是传递响应状态的通用代码,因此,要真正实现RESTful,应用程序必须使用这个框架来通信响应状态。

在HTTP 200信封中发送错误响应具有误导性,并迫使客户端(api使用者)解析消息,很可能以非标准或专有的方式。这也是低效的——您将迫使您的客户端每次都解析HTTP有效负载以了解“真实的”响应状态。这增加了处理,增加了延迟,并为客户端创建了一个出错的环境。

我知道这已经是姗姗来迟了,但是现在,在2013年,我们有了一些媒体类型来以通用的分布式(RESTful)方式处理错误。参见“application/vnd. error”;error+json (https://github.com/blongden/vnd.error)和“HTTP api的问题细节”,应用程序/问题+json (https://datatracker.ietf.org/doc/html/draft-nottingham-http-problem-05)。

为你的API选择正确的HTTP错误代码的一个很好的资源: # EYZ0 < / p >

文章节选如下:

从哪里开始:

enter image description here

2 xx / 3 xx:

enter image description here

4 xx:

enter image description here

5 xx:

enter image description here

请遵守协议的语义。使用2xx表示成功响应,使用4xx和5xx表示错误响应——无论是您的业务异常还是其他。如果协议中的预期用例是使用2xx进行任何响应,那么它们首先就不会有其他状态码。