6

I stumbled over a practice that I found to be quite widespread. I even found a web page that gave this a name, but I forgot the name and am not able to find that page on google anymore.

The practice is that every JSON response from a REST service should have the following structure:

{
    "status": "ok",
    "data": { ... }
}

or in an error case:

{
    "status": "error",
    "message": "Something went wrong"
}

My question: What is the point why such a "status" property should be required in the JSON? In my opinion that is what HTTP status codes were made for.

REST uses the HTTP means of communication between client and server, for example the "DELETE" verb should be used for deleting. In the same way, 404 should be used if a resource is not found, etc. So inline with that thinking, any error cases should be encoded properly in the HTTP status.

Are there specific reasons to return a HTTP 200 status code in an error case and have the error in the JSON instead? It just seems to make the javascript conditional branches more complex when processing the response.

I found some cases where status could be "redirect" to tell the application to redirect to a certain URL. But if the proper HTTP status code was used, the browser would perform the redirection "for free", maintaining the browsing history properly.

I picture mainly two possible answers from you:

  • Either there are two quarreling communities with their favorite approach each (use HTTP status always vs. use HTTP status never)
  • or I am missing an important point and you'll tell me that although the HTTP status should be used for some cases, there are specific cases where a HTTP status does not fit and the "status" JSON property comes into play.
chiccodoro
  • 14,407
  • 19
  • 87
  • 130

3 Answers3

4

You are right. I think what you are seeing is a side-effect of people not doing REST correctly. Or just not doing REST at all. Using REST is not a pre-requisite for a well-designed application; there is no rule that webapps have to be REST-ful.

On the other hand, for the error condition, sometimes apps want to return a 200 code but an error to represent a business logic failure. The HTTP error codes don't always match the semantics of application business errors.

hvgotcodes
  • 118,147
  • 33
  • 203
  • 236
3

You are mixing two different Layers here:

  • HTTP is for establishing (high-level) connections and transferring data. The HTTP status codes thus informs you if and how the connection was established or why it was not. On a successful connection the body of the HTTP request could then contain anything (e.g. XML, JSON, etc.), thus these status code have to define a general meaning. It does not inform you about the correctness or type (e.g. error message or data) of the response.

  • When using JSON for interchanging data you could certainly omit the status property, however it is easier for you to parse the JSON, if you know if it includes the object you were requesting or an error message by just reading one property.

So, yes, it is perfectly normal to return a 200 status code and have a "status": "error" property in your JSON.

Jan Gerlinger
  • 7,361
  • 1
  • 44
  • 52
  • +1 - Exactly, this JSON pattern allows you to report *application level* errors. HTTP is not designed to report errors at this layer. – Justin Ethier Jul 11 '12 at 13:39
  • This answer is 20x better than mine. – Tom van der Woerdt Jul 11 '12 at 22:38
  • 2
    Justin - in REST, HTTP is meant to be used to report application level errors. – Brian Kelly Jul 12 '12 at 03:34
  • Brian - No, REST is just a style and not bound to HTTP (see ["REST does not restrict communication to a particular protocol"](http://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm#sec_5_3_2)). Just because many services use HTTP status codes for reporting application level errors, you can't say it is "meant to be" like that. – Jan Gerlinger Jul 12 '12 at 07:57
  • Thanks for the clarification. I can see your point now. From a HTML document point of view I would have argued, no, TCP is the transport, HTTP is the business. HTTP 404 means document not found; HTTP 201 means document created, etc. That is also what REST suggests to use where applicable. But I realized there can be buisness related errors such as "you cannot change the status of this ticket from in progress to resolved because according to the workflow you need to meet this and that precondition first" which definitely does not map to any HTTP status code... – chiccodoro Jul 13 '12 at 14:23
2

HTTP status codes can be caused by a lot of things, including load balancers, proxies, caches, firewalls, etc. None of these are going to modify your JSON output, unless they completely break it, which can also be treated as an error.

Bottom line: it's more reliable to do it via JSON.

Tom van der Woerdt
  • 29,532
  • 7
  • 72
  • 105
  • 1
    would that boil down to the application returning an 4xy HTTP status code *plus* a JSON body with an explanation if there is a business error? Return 200 in an error case just feels wrong to me and can have bad side effects if not treated correctly. – chiccodoro Jul 11 '12 at 13:20
  • 1
    Yeah, using both is what I would recommend. – Tom van der Woerdt Jul 11 '12 at 13:34