REST API错误返回良好实践

时间:2009-06-03 03:39:17

标签: web-services http rest

我正在寻找有关从REST API返回错误的良好做法的指导。我正在开发一个新的API,所以我现在可以采取任何方向。我的内容类型目前是XML,但我计划将来支持JSON。

我现在正在添加一些错误案例,例如客户端尝试添加新资源但已超出其存储配额。我已经使用HTTP状态代码处理某些错误情况(401用于身份验证,403用于授权,404用于普通错误请求URI)。我查看了有福的HTTP错误代码,但400-417范围似乎没有报告特定于应用程序的错误。所以起初我很想用200 OK和特定的XML有效载荷返回我的应用程序错误(即付给我们更多,你将得到你需要的存储空间!)但是我停下来思考它并且似乎是肥皂(/耸耸肩恐怖)。此外,感觉就像我将错误响应分成不同的情况,因为有些是http状态代码驱动而其他是内容驱动。

那么行业建议是什么?好的做法(请解释原因!)以及从客户端pov中,REST API中的哪种错误处理使客户端代码的生活更轻松?

12 个答案:

答案 0 :(得分:527)

为您的API选择正确的HTTP错误代码的绝佳资源: http://www.codetinkerer.com/2015/12/04/choosing-an-http-status-code.html

摘自文章:

从哪里开始:

enter image description here

2XX / 3XX:

enter image description here

4XX:

enter image description here

5XX:

enter image description here

答案 1 :(得分:213)

  

所以起初我很想用200 OK和特定的XML有效负载返回我的应用程序错误(即付给我们更多,你将得到你需要的存储空间!)但我停下来思考它似乎肥皂(/耸耸肩)。

除非请求确实没有任何问题,否则我不会返回200。从RFC2616开始,200表示“请求已成功。”

如果超出客户的存储配额(无论出于何种原因),我将返回403(禁止):

  

服务器理解请求,但拒绝履行请求。授权无效,请求不应重复。如果请求方法不是HEAD并且服务器希望公开为什么请求没有得到满足,那么它应该描述实体中拒绝的原因。如果服务器不希望将此信息提供给客户端,则可以使用状态代码404(未找到)。

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

您有什么其他特定错误条件?

答案 2 :(得分:86)

主要的选择是,您是否希望将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状态代码和指示应用程序级问题的自己的状态代码。

  4. 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. 这种方法对于客户来说更容易,因为响应的状态总是在同一个地方(不需要子代码),代码没有限制,不需要获取HTTP级别的状态代码

    4. 这是一篇有类似想法的帖子:http://yuiblog.com/blog/2008/10/15/datatable-260-part-one/

      主要问题:

      1. 请务必提供版本号,以便日后根据需要更改api的语义。

      2. 文档...

答案 3 :(得分:40)

请记住,状态代码多于HTTP / 1.1 RFC中定义的状态代码,IANA注册表位于http://www.iana.org/assignments/http-status-codes。对于你提到的状态代码507听起来正确的情况。

答案 4 :(得分:22)

正如其他人所指出的那样,在错误代码中使用响应实体是完全可以允许的。

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

答案 5 :(得分:19)

我知道派对非常晚,但是现在,在2013年,我们有一些媒体类型来覆盖常见的分布式(RESTful)方式的错误处理。请参阅“vnd.error”,application / vnd.error + json(https://github.com/blongden/vnd.error)和“HTTP API的问题详细信息”,application / problem + json(https://tools.ietf.org/html/draft-nottingham-http-problem-05)。

答案 6 :(得分:18)

有两种错误。应用程序错误和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 )

2xx成功

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时的错误消息)。

答案 7 :(得分:9)

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

在HTTP 200信封中发送错误响应会产生误导,并迫使客户端(api使用者)解析消息,最有可能是以非标准或专有方式。这也没有效率 - 您将强制客户端每次解析HTTP有效负载以了解“真实”响应状态。这增加了处理,增加了延迟,并为客户创造了犯错的环境。

答案 8 :(得分:6)

根据现有的“最佳实践”对api进行建模可能是最佳选择。 例如,Twitter是如何处理错误代码的 https://developer.twitter.com/en/docs/basics/response-codes

答案 9 :(得分:5)

请坚持协议的语义。使用2xx进行成功响应,使用4xx,5xx进行错误响应 - 无论是您的业务异常还是其他。如果任何响应使用2xx作为协议中的预期用例,则它们首先不会有其他状态代码。

答案 10 :(得分:3)

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

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

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

答案 11 :(得分:-1)

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