关于Web服务:REST API错误返回良好实践

REST API error return good practices

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

我现在添加了一些错误案例,例如,客户机试图添加新资源,但已超出其存储配额。我已经使用HTTP状态代码处理了某些错误案例(401用于身份验证,403用于授权,404用于纯错误请求URI)。我查看了幸运的HTTP错误代码,但400-417范围中的任何一个似乎都不适合报告特定于应用程序的错误。所以一开始我很想返回我的应用程序错误,有200OK和一个特定的XML负载(即,支付我们更多的钱,您就可以得到所需的存储空间!)但我停下来想了想,这似乎是肥皂剧(/耸耸肩在恐怖)。此外,我感觉我正在将错误响应拆分为不同的情况,其中一些是HTTP状态代码驱动的,另一些是内容驱动的。

那么,行业建议是什么?良好实践(请解释原因!)而且,从客户机POV来看,RESTAPI中的哪种错误处理使客户机代码更容易使用?


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

文章摘录:

从哪里开始:

enter image description here

2xx/3xx:

氧化镁

4xx:

氧化镁

5xx:

氧化镁


So at first I was tempted to return my application error with 200 OK and a specific XML payload (ie. Pay us more and you'll get the storage you need!) but I stopped to think about it and it seems to soapy (/shrug in horror).

我不会退回200,除非请求真的没有问题。从RFC2616中,200表示"请求已成功"。

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

The server understood the request, but is refusing to fulfill it. Authorization will not help and the request SHOULD NOT be repeated. If the request method was not HEAD and the server wishes to make public why the request has not been fulfilled, it SHOULD describe the reason for the refusal in the entity. If the server does not wish to make this information available to the client, the status code 404 (Not Found) can be used instead.

这会告诉客户机请求是正常的,但是失败了(200不能做)。这也为您提供了在响应主体中解释问题(及其解决方案)的机会。

您还考虑了其他哪些特定的错误条件?


主要的选择是是否将HTTP状态代码视为RESTAPI的一部分。

两种方法都可以。我同意,严格地说,REST的一个想法是,您应该将HTTP状态代码作为API的一部分(返回200或201表示操作成功,4xx或5xx取决于各种错误情况)。但是,没有REST警察。你可以做你想做的。我已经看到了更多令人震惊的非RESTAPI被称为"RESTful"。

此时(2015年8月),我建议您使用HTTP状态代码作为API的一部分。现在在使用框架时看到返回代码比过去容易得多。特别是,现在比过去更容易看到非200退货案例和非200回复主体。

HTTP状态代码是API的一部分

  • 您需要仔细选择适合您的错误条件的4xx代码。您可以将REST、XML或纯文本消息作为包含子代码和描述性注释的有效负载。

  • 客户机将需要使用一个软件框架,使他们能够获得HTTP级别的状态代码。通常都能做到,而不是总是直截了当。

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

  • HTTP状态代码不是API的一部分

  • 如果您的应用程序收到请求然后响应(成功和错误情况),则HTTP状态代码将始终为200。

  • 您的所有回复都应该包括"信封"或"标题"信息。通常是这样的:

    1
    2
    3
    4
    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.
  • 由于响应的状态总是在同一位置(不需要子代码),代码没有限制,不需要获取HTTP级别的状态代码,因此对于客户机来说,此方法更容易实现。

  • 以下是一篇有类似想法的文章:http://yuiblog.com/blog/2008/10/15/datatable-260-part-one/

    主要问题:

  • 请确保包含版本号,以便以后在需要时更改API的语义。

  • 文档…


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


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

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


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


    有两种错误。应用程序错误和HTTP错误。HTTP错误只是为了让Ajax处理程序知道事情进展顺利,不应该用于其他任何事情。

    5xx服务器错误

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    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成功

    1
    2
    3
    4
    5
    6
    7
    8
    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)

    但是,如何设计应用程序错误实际上取决于您自己。例如,堆栈溢出发送具有responsedatamessage属性的对象。我认为响应包含truefalse,以指示操作是否成功(通常用于写操作)。数据包含有效载荷(通常用于读取操作),消息包含任何额外的元数据或有用的消息(例如,当responsefalse时的错误消息)。


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

    在HTTP200信封中发送错误响应是一种误导,并迫使客户机(API使用者)以非标准或专有的方式解析消息。这也是不高效的——您将强制客户机每次分析HTTP负载以了解"真实"的响应状态。这增加了处理速度,增加了延迟,并为客户机创建了出错的环境。


    在现有的"最佳实践"上建模您的API可能是可行的方法。例如,Twitter如何处理错误代码https://developer.twitter.com/en/docs/basics/response-codes网站


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


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

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

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


    如果超过了客户机配额,这是一个服务器错误,请在此实例中避免使用5xx。