Many web services use HTTP status codes incorrectly. The human web hardly uses them at all. Human beings discover what a document means by reading it, not by looking at an attached numeric code. You’ll see “404” in an HTML page that talks about a missing document, but your attention is on the phrase “missing document,” not on the number. And even the “404” you see is part of the HTML page, put there for human convenience: your browser doesn’t show you the underlying 404 response code.
So when there’s an error condition on the human web, most applications send a response code of 200 (“OK”), even though everything’s not OK. The error condition is described in an HTML entity-body, and a human being is supposed to figure out what to do about the error. The human never sees the response code in the first place, and the browser treats most response codes the same way, so why should the server bother picking the “right” code for a given situation?
On the programmable web, there are no human beings guiding the behavior of clients. A computer program can’t reliably figure out what a document means just by looking at it. The same document might be an error message in one context, and the legitimate fulfillment of a GET request in another. We need some way of signalling which way of looking at the response is correct. This information can’t go into the entity-body document, because then getting it out would require an understanding of the document. So on the programmable web, HTTP response codes become very important. They tell a client how to deal with the document in the entity-body, or what to do if they can’t understand the document. A client—or an intermediary between server and client, like a firewall—can figure out how an HTTP request went, just by looking at the first three bytes of the response.
The problem is that there are 41 official response codes, and standards like WebDAV add even more. Many of the codes are rarely used, two of them are never used, and some are only distinguishable from one another by careful hairsplitting. To someone used to the human web (that’s all of us), the variety of response codes can be bewildering.
In this appendix I give a brief explanation of every standard status code, with tips on when to use each one in your RESTful services, and my personal opinion as to how important each one is in the context of this book. If a client has to do something specific to get a certain response code, I explain what that is. I also list which HTTP response headers, and what kind of entity-body, the server ought to send along with a response code. This is an appendix for the web service author, but it’s also for the client author, who’s received a strange response code and doesn’t know what it means.
I cover all 41 codes from the HTTP standard, even though some of them (mainly the ones to do with proxies) are a little beyond the scope of this book. I also cover 207 (“Multi-Status”), a response code from the WebDAV extension which I mentioned back in Chapter 8. WebDAV defines five response codes besides 207, and some web servers define the nonstandard code 509 (“Bandwidth Limit Exceeded”). Though not part of HTTP, these status codes are fairly well established, and you can use them if you like. I don’t cover them because they’re more explicit versions of standard response codes. You can always send 503 (“Service Not Available”) instead of the 509 response code, and 409 (“Conflict”) instead of WebDAV’s 423 (“Locked”). I cover 207 (“Multi-Status”), because no standard status code does anything similar.
If you don’t like the proliferation of status codes, you can serve just three and still convey the basic information a client needs to know to handle the response.
Everything’s fine. The document in the entity-body, if any, is a representation of some resource.
There’s a problem on the client side. The document in the entity-body, if any, is an error message. Hopefully the client can understand the error message and use it to fix the problem.
There are four more error codes that are especially common in web services:
Sent when the client requests a URI that doesn’t map to any resource. 404 is used when the server has no clue what the client is asking for. 410 is used when the server knows there used to be a resource there, but there isn’t anymore.
SOAP web services use only the status codes 200 (“OK”) and 500 (“Internal Server Error”). The 500 status code happens whether there’s a problem with the data you sent the SOAP server, a problem with processing the data, or an internal problem with the SOAP server itself. There’s no way to tell without looking at the body of the SOAP document, which contains a descriptive “fault.” To know what happened with the request you can’t just look at the first three bytes of the response: you have to parse an XML file and understand what it says. This is another example of how Big Web Services reimplement existing features of HTTP in opaque ways.