当涉及到REST API的返回错误时,我正在寻找关于良好实践的指导。我正在开发一个新的API,所以我现在可以把它带到任何方向。目前我的内容类型是XML,但我计划将来支持JSON。
I am now adding some error cases, like for instance a client attempts to add a new resource but has exceeded his storage quota. I am already handling certain error cases with HTTP status codes (401 for authentication, 403 for authorization and 404 for plain bad request URIs). I looked over the blessed HTTP error codes but none of the 400-417 range seems right to report application specific errors. 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). Besides it feels like I'm splitting the error responses into distinct cases, as some are http status code driven and other are content driven.
那么行业建议是什么呢?好的实践(请解释为什么!),并且,从客户端角度来看,REST API中什么样的错误处理可以使客户端代码更容易?
因此,一开始我想用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的一部分
You will need to carefully pick 4xx codes that fit your error conditions. You can include a rest, xml, or plaintext message as the payload that includes a sub-code and a descriptive comment.
The clients will need to use a software framework that enables them to get at the HTTP-level status code. Usually do-able, not always straight-forward.
The clients will have to distinguish between HTTP status codes that indicate a communications error and your own status codes that indicate an application-level issue.
HTTP状态代码不是api的一部分
The HTTP status code will always be 200 if your app received the request and then responded (both success and error cases)
ALL of your responses should include "envelope" or "header" information. Typically something like:
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.
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.
这里有一个类似的想法:http://yuiblog.com/blog/2008/10/15/datatable-260-part-one/
主要问题:
请确保包含版本号,以便稍后在需要时更改api的语义。
文档…
有两种错误。应用程序错误和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发送一个具有响应、数据和消息属性的对象。我认为响应包含true或false,以指示操作是否成功(通常用于写操作)。数据包含有效负载(通常用于读取操作),消息包含任何额外的元数据或有用消息(例如响应为false时的错误消息)。