Is there a conventional way of returning error statuses from JSON web services?
I have a .NET .ashx handler, which receives a jQuery AJAX post, formats a web service request to a third-party service and consumes the result. On success, it instantiates an anonymous object with the relevant information and formats a JSON response string.
In the event of a web service error, I do the following:
context.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
context.Response.StatusDescription = wsResult.ErrorCode;
This makes both the status code and description easily accessible to the jQuery AJAX error callback; however, the way I have implemented this is quite arbitrary.
After doing some reading around, I can't find a conclusive answer to the following question: Is there an accepted, universal convention (or - even - specification) for returning error states to JSON-based AJAX calls, which allows any consumer to know what to expect, or is this as arbitrary as a return type for any other function call?
So, is this a perfectly acceptable way of returning an error status to the AJAX caller, or is there a "proper" way of formatting a JSON error response?
As others have said, there's no universal convention. The REST "community" is still in the process of finding some consensus in matters like these - a consensus may never be found. Just to give a few examples:
Status code
By default ServiceStack.NET, a widely used C# REST library web service framework, returns the object (or empty response) with a status code, eg:
201 Created
Or:
200 OK
In the case of a validation error (eg an ArgumentException
), it may do eg:
400 Bad Request
And here's already the first point where things start to vary. Some people like the 400
status code for things like validation errors - others don't, since 400
really indicates malformed syntax in the request format itself.
Some prefer 422 Unprocessable Entity
for validation errors, a WebDAV extension to the HTTP protocol, but still perfectly acceptable technically.
Others think you should simply take one of the error status codes unused in the HTTP protocol, eg 461
. Twitter have done that with (among others) 420 Enhance Your Calm
to notify a client that they're now being rate limited - even if there's an (on the surface) acceptable (and recommended) status code 429 Too Many Requests
for that purpose already.
Etc. It's all a matter of philosophy.
As for 500 Internal Server Error
, the same applies - some think it's perfectly fine for all kinds of error responses, others think that the 5xx
errors should only be returned on exceptions (in the real sense - ie, exceptional errors). If the error is truly exceptional, you mostly wouldn't want to take the chance and pass on any actual exception info, which may reveal too much about your server.
Leading us to what (if anything) to return in the JSON result? Same thing...
Response
200 OK
may be quite enough for responding to eg a request to delete a resource, if no error occurred. In the same way, 404 Not Found
is enough to tell the client that the requested deletion couldn't be performed because the entity to delete wasn't found. In other cases you may require more than that.
Some people think you should include as much of the needed info as possible in the response headers, often having an empty response with only headers. For example, on a creation, return 201 Created
and put the created entity's ID (as a resource URI) in Content-Location
. No response content needed.
I personally think that if you're making a public API, it's a good idea to return both appropriate headers and content, even if the content is somewhat redundant. Ie:
HTTP/1.1 404 Not found
Content-Type: application/json; charset=utf-8
...
{
'Success': false,
'Message': 'The user Mr. Gone wasn't found.'
}
(I don't actually include the Success
property, but I might want to, depending on my frame of mind when designing the API).
When running in DEBUG mode, I also include a string representation of the internal service call - eg 'Request': 'GetUser { id: 5 }'
, a timestamp, and the stack trace. It's all a matter of convenience, though. It's easy enough to code a client with proper user friendly error messages simply based on 404 Not found
. Some other errors (eg validation) may need more context, though. For example:
HTTP/1.1 422 Validation Error
Content-Type: application/json; charset=utf-8
...
{
'Success': false,
'Message': 'The request had validation errors.',
'Errors':
{
'UserName': 'The user name must be provided.',
'Email': 'The email address is already in use.'
}
}
ServiceStack.NET does something like this by default, but with slightly different properties and content. Microsoft's own Web API framework does something similar. The JSend spec linked in the related question is another variation.
And so on.
In short, no, there isn't any universal convention - not yet, at least. Lots of people (putting more thought into it than I) are working on it. But still, there may never be. And your method is perfectly acceptable.
(Yes, this was very lengthy - mostly because I've been searching around for the same kind of "universal convention" for a while).
For more on status codes, this is an excellent article (too long to quote here)
No, there is not any single major standard out there, although this might be nice. It might be useful if you are making yourself a standard to include success
and details
, but it depends on exactly how you are using it. I think the big advantage is when you implement a standard at least across all of your own code for consistency, eg http://ricardocovo.com/2012/03/08/asp-net-mvc-using-json-standard-responses-for-your-ajax-calls/
Your response is completely acceptable if it's fitting your needs. If I was working with an API, I would see that error response as 'standard', containing a response code and description, although I might like a boolean success
for ease of use.
My 2 cents:
I would say that foremost the statuscode that you send back as the response is the best error indicator and gives a lot of options in the 4xx and 5xx range... (Even when you try to HttpGET some coffee from a teapot, you can use 418 :D)
As anything that is not 200 is some sort of error, and the http status codes are well documented in which case they should be used, any further error message is not really necessary (The error description is implied by the statuscode). Browsers are the ones doing the request, and they don't care about the errormessage, only the statuscode.
Any extra errormessages might also just away too much information to possible hack attempts. I mean, returning a 403 Forbidden is enough information on its own, you shouldn't also return a message saying "Not allowed, please use '1234' as the password instead" :)
链接地址: http://www.djcxy.com/p/48062.html