The case for not using HTTP status codes (and thus breaking the cacheability and layering which are key to the REST model) is very weak. I just don't see why it all has to be wrapped in so many layers. GET /posts.json should return a list, GET /posts/1.json should return an object, and DELETE /post/1.json should result in a HTTP 204 if successful. In the case of errors, the response's status code and an object with exception information should suffice.
Something like this makes sense for JSONP, where you can't use HTTP status codes because the handler for the JSONP response doesn't get called at all if the status code is anything other than 200. In this case embedding a "status" field in the response is necessary to communicate errors.
If an ill-conceived client sends HTTP requests yet drops HTTP status codes on the floor, I have no doubt that coddling it by also breaking the server (200 OK, {"status":"fail"}? wtf?) will catch on despite being an amazingly bad idea. This is why we can't have nice things.
Many modern-day streaming protocols are built on top of HTTP purely because firewalls don't block it and proxies can forward it. Obviously that's a terrible idea from a performance point of view, but it's a fact of life that things are broken and we can deal with it by moving up the protocol stack.
Feel free to try and make (400 Bad Request, {"details": "whatever"}) work when your Javascript code is injected into someone else's code running on their own domain. If you can - and not require users to be using a particular browser version - you will make mashup and browser extension authors very happy.
If I really wanted to cater to such insanely reckless third parties who can't proxy through their own servers, I'd leave my real services unchanged (so they can still be consumed by non-broken clients) and add a js proxy service that can call any of my real services, and return a response with js that stuffs a description of the real response into an object supporting the XMLHttpRequest interface (especially including getResponseHeader(), status, and statusText). That way the caller can treat XHR as a uniform API for handling responses, even for those cases where they had to resort to an ugly hack rather than XHR to actually get the request on the wire.
I agree, I am absolutely not a fan of this. REST is about documents; documents do not contain status information about the transport protocol used to transfer them, they just contain the free-form data that the application wants to convey to you.
For example, imagine the document at /foo/bar has moved to /new-api/foo/bar. Well, if you use HTTP for status, the server sends a 302 redirect when you try to request /foo/bar, and the user agent automatically grabs /new-api/foo/bar. If we reinvent this wheel for some reason, you can't use HTTP clients anymore, you have to use some proprietary bullshit client instead.
No thanks. This is not a problem and it does not need a "solution".
(I also agree about 204 responses for DELETE requests. The thing is gone, why does any data need to be sent back other than, "yeah, it went away"?)
The document is now in the data field of the returned JSON. It's just an extra header/footer, similar to having meta http-equiv tags. Because it helps limited HTTP clients like JSONP, many web APIs already use this form, but they all use different syntax, which is the problem this "standard" is addressing.
I'm not sure but there is difference between: 1) an application server accepts client request but fails to execute it, so client gets an error via JSON and 2) something on server side (HTTP server or application server or firewall) fails to receiver/accept client's request thus client gets back some HTTP error code.
Maybe people like this way becasue in complex systems there is always difference between failure to deliver and understand the request and error during execution of the request.
Indeed. If you really need layer upon layer of abstraction, why not go back to the XMLRPC protocols?
The charm of JSON, to me, is its simplicity: that it can run on a bare HTTP server without worrying about dispatching, using a special library with a schema to strictly format responses, and so on.
If I understood correctly, the JSend statuses should be used in conjunction with HTTP status codes when appropriate. I guess to me the spec seems redundant, as I don't see the advantage over using just HTTP status codes.
Sure, HTTP status codes should be used. But they aren't enough to communicate application-specific messages from an app backend to an AJAX front-end. For example, AJAX on the browser might submit a form and the server returns a 422 (HTTP validation error status code). How will you be able to inform the user that the "email address must contain @" or "foobar is not an acceptable name"? You need to consume some JSON that has a payload of application-specific status messages.
I don't know if this proposal is optimal (smarter guys than me can decide that). But I know that a standard way of communicating application-specific errors would be a big step forward.
A year ago I searched for an adequate in-place editing plugin for Rails that didn't require major surgery to provide error messages to the user. I was surprised at the complexity required to handle a simple error condition. Usually Rails has all the goodness baked in but it seems application-specific status messages with JSON are out of scope. I asked "How to show server errors in Rails with JSON and jQuery" [1] on Stack Overflow and it's received more views than any other question I've ever asked.
Exactly. I am constantly amazed at how oftem people tack the word REST onto things that are clearly not RESTful, and in some cases (like this one) specifically unRESTful.
Please, people: REST does not simply mean "HTTP is involved somewhere".
Enjoying the discussion. The argument that HTTP status codes are "good enough" is one perspective. While I don't buy into everything in the "spec" proposed here, I think having application specific errors that make more sense is reasonable.
While I might no agree with everything presented in the project, I do agree that it is somewhat arbitrary (and certainly complex) mapping HTTP status codes into every JSON API.
The one thing I could see this being useful for is standardizing pagination for large result sets. Ideally, the server would return meta pagination information that includes total number of results, offset, limit, etc.
Unfortunately, this spec doesn't address that at all as far as I can tell :(
Why not just return NULL on failure and the data object on success? in most cases that will work, in some cases it will not be enough, but why add redundant data to all responses?