Given an HTTP server (e.g. Apache, IIS) and a web application (user code running in the server using PHP, ASP.NET and the likes), which of those can decide which HTTP status code to return for any request?
Or rather, is a “web application” to be interpreted as an integral part of “server” as used in the HTTP RFCs? The latter (RFC 7230) is pretty short on that:
An HTTP “server” is a program that accepts connections in order to service HTTP requests by sending HTTP responses.
Since the actual response is generated by a web application (excluding static resources), I’d say the web application is actual part of the server.
However, apart from the eternal “which HTTP status code to use in [arbitrary situation]?” discussions, there also is the discussion “Should web applications even use HTTP status codes?”, which I’d like a normative answer to.
See for example the Google Maps REST API. They return 200 for every repsonse, which can be interpreted as “The request ended up at the HTTP server, so that part went OK (200)”. Any application error that happens that is returned in the message body as a JSON status, up till the point of NOT_FOUND
.
Is this correct? Shouldn’t a request for GET /Clients/123
return a 404
when that client doesn’t exist? Then what about GET /clients.php?id=123
, assuming clients.php
exists?
Or does 404
really and only mean “I don’t know what you’re trying to do, but I’m not going to serve you a resource as there is no resource at (a part of) that URI”, “resource” meaning “a (routed) file or directory”, which should only be returned by the server when someone forgot to deploy the ClientService application?
Do status code only work for the HTTP part of things, or is a web application part of the server, allowing it to utilize the appropriate status codes where they fit, using HTTP status codes as API response codes?
404 means “the resource you asked for doesn’t exist.” It’s up to the server to decide when that response is appropriate. Google has apparently interpreted it to mean “your API request was malformed.” Other REST APIs might also interpret it to mean “your request was well-formed, but you are asking for something which does not exist.” This is why you need to read the API docs.
The “server,” in turn, is (as your RFC quote indicates) anything that responds to HTTP requests appropriately. If you build a server out of a gigantic web application framework, that’s your business. The only requirement is that the client gets the semantically-correct response in any given situation. It will often be the case that the web application is better suited to make that decision than (say) Apache’s out-of-the-box behavior, but you can and should set this up in whatever way makes the most sense for your situation.
3
When dealing with HTTP status codes the level of abstraction to be thinking on is the context of the HTTP request that was just made.
If your client makes a request
GET http://example.com/someresource
your client is saying
Yo! example.com! Give me a representation of "someresource"
If the client cannot do that then do not return 200 (OK). What Google do is wrong. Saying “OK! I cannot do that” is a confused response.
Imagine if you went into a shop and said give me a 6 pack of beer and the shop keeper said “Ok here you go” and then when you looked down into your bag there was a letter saying “Sorry, all out of beer”!
The client does not care about the internal workings of example.com, in the same way you don’t care about the problems the shop may or may not be having. You care if you can get your beer.
If you cannot get your beer you only care if you have done something wrong (“Sorry, I need ID”) or if there is nothing more you can do (“Sorry we are all out of beer” or “Sorry this is a knitting store, we don’t sell beer”). The sorry I cannot give you that resource responses are 4xx and 5xx
If example.com has to talk to 100 different servers or databases to do what the client asked the client doesn’t care, any more than you care if the shop keeper has to shout over the intercom “Hey! I need some more beer!” in order to give you the beer. You don’t care, you care about the beer.
3