We Suck at HTTP

By Deane Barker on January 7, 2015

I absolutely loved this New York Times column which lamented the world of apps, where we don’t have the capability to link to content anymore:

Unlike web pages, mobile apps do not have links. They do not have web addresses. They live in worlds by themselves, largely cut off from one another and the broader Internet. And so it is much harder to share the information found on them.

Yes, yes, for the love of God yes.

We have broken HTTP.  We’ve done it for years in fits and starts, but apps have completely broken it.  HTTP was a good specification which we’ve steadily whittled away.

URLs have a purpose.  We are very cavalier about that purpose. We don’t use canonicals. We’re sloppy about switching back and forth between HTTP and HTTPs.  We don’t bother to logically structure our URLs.  We rebuild websites and let all the links break. We don’t appreciate that crawlers are dumb and they need more context than humans.

Did you know there’s something called a URN – Uniform Resource Name?  This was supposed to be one level above a URL.  Your resource would have a URN, which would be a global identifier, and it would resolve to a URL which was just where the resource was located right now.  URNs never caught on, but they web would be better if they had.  Content could then have a “name” which was matched to it forever, regardless of its current URL.  (The “guid” element in RSS probably should have been named “urn,” in fact.)

And it’s not just URLs.  HTTP status codes exist for a reason too.  Did you know that there are a lot of them?  In fact, there’s one for about everything that could happen for a web request.  Did you know there’s a difference between 404 and 410?  404 (traditionally “Not Found”) means it was never here.  410 (traditionally “Gone”) means* it was once here but is now gone*.  Big difference.

Ever hear of 303 and 307?  They’re meant for load redirects (mirrors).  The human readable descriptions are usually “See Other” or “Temporary Redirect."  Did you know there was a “402 Payment Required”?  There’s a bunch that were just never implemented. These days a lot of websites just return “200 OK” for everything, even 404s, which drives me freaking nuts.  (And, yes, I’m sure I’ve done it, so don’t go looking too hard through my portfolio...)

(A new company called Words API (it’s an API...for words) made me jump for joy when I saw they are using actual, intelligent HTTP status codes on their responses, even their errors.  If you go over your usage limit, for example, you get a “429 Too Many Requests “ back. Good for them.)

Do you know why your FORM tag has an attribute called “method”?  Because you’re calling a method on a web server, like a method on an object in OOP.  Did you know there are other methods besides GET and POST?  There’s HEAD and OPTIONS and PUT and DELETE.  And you can write your own.  So if you’re passing data back and forth between your app/site and your web server, you’re welcome to name custom methods in the leading line of the header.

And, technically, you’re supposed to make sure GET requests are idempotent, meaning they can be repeated with no changes to a resource.  So you should be able to hit Refresh all day on a GET request without causing any data change (beyond perhaps analytics).  If you’re changing data on a server, that should always be a POST request (or PUT or DELETE, if anyone ever used them as intended).

I could go on and on.  Don’t even get me started about URL parameters. No, not querystrings – there was originally a specification where you could do something like “/key1:value1/key2:value2/” to pass data into a request. And what about the series of “UA-” headers that existed to tell the web server information about the rendering capabilities of the user agent?  (And dare I wander off into metadata-related ranting...two words people, Dublin Core!*)

My point is that a lot of web developers today are completely ignorant of the protocol that is the basis for their job.  A core understanding of HTTP should be a base requirement for working in this business.  To not do that is to ignore a massive part of digital history (which we’re also very good at).

I’m currently working through HTTP: The Definitive Guide by O’Reilly.  The book was written in 2002, but HTTP hasn’t changed much since then.  It’s fascinating to read all the features built into HTTP that no one uses because they were never adopted or no one bothered to do some research before they re-solved a problem. There’s a lot of stuff in there that solves problems we’ve since programmed our way around.  The designers of the spec were probably smarter than you, it turns out.

(HTTP/2 is currently proposed, but it doesn’t change much of the high level stuff.  The changes are mostly low-level data transport hacks, based on Google’s experience with SPDY.)

At risk of sounding like a crabby old man (I’m 43 and have been developing for the web since 1996), this is one small symptom of a larger problem – developers tend to think they can solve every problem, and they’re pretty sure that nothing good happened before they arrived on the scene. Anyone working in this space 20 years ago couldn’t possibly have known of their problems so every problem deserves a new solution.

Developers often don’t know what they don’t know (that link goes to my personal confession of this exact thing), and they feel no need to study the history of their technology to gain some context about it.  Hell, we all need to sit and read The Innovators together.

Narcissism runs rampant in this industry, and our willingness to throw away and ignore some of the core philosophies of HTTP is just one manifestation of this.  Rant over.

Comments (43)

John Titus says:

Thanks for the kind words. As a developer, and a frequent consumer of APIs, I hate it when they don’t use HTTP status codes. Instead you’ll get a lot of 200’s with a text message saying an error occurred, which means a human has to parse the error instead of leaving it up to the code. Drives me crazy too!

stelt says:

see DOI (like URN)

Dan Porter says:

There was a great article about the permalink structure BBC have used on their site since the early days, except I can’t find it, as it was shared through Facebook over a year ago. Point proven I suppose.

Chris Schagen says:

People do crazy things with And just looking at gadgetopia, we have 4308 response codes in total, of which: - 115 no response – 2648 success (2xx) - 1302 Redirection (3xx) - 234 Client error (4xx) - 9 Server error (5xx)

Some housekeeping seems to be in order, Deane ;) You really only want to have 200 in your internal link graph... Though I am probably preaching to the choir here...

Chris Schagen says:

Aww, wanted to say “ People do crazy things with status codes, and find many new ways of shooting themselves in the foot. From 7 levels of internal redirection chains, to putting everything on 404 after a relaunch, 200’ing clear error pages, etc”

Michael Smith says:

The distinction between 404 and 410 is broken in design, IMO. Quoth the W3C about 410:

If the server does not know, or has no facility to determine, whether or not the condition is permanent, the status code 404 (Not Found) SHOULD be used instead.

Do you know how to generalize (programmatically or otherwise) whether a condition is permanent? I don’t. In fact, it seems to me that nothing can be guaranteed to be permanent, including gone-ness. So when should you use 410 Gone? Practically never, according to its own spec.

I don’t think that’s right. I think we should ignore that phrase in the spec and use 410 Gone when the server 1. Knows that a resource used to exist, 2. It doesn’t exist anymore, 3. There’s no reasonable reason to expect it to come back.

But that’s just me.

John Sheehan says:

Typically you use 410 over 404 in response to a DELETE. This lets you know if the thing you were trying to delete existed and is now gone or if it was never there in the first place.

Understanding HTTP is vitally important for modern devs. The importance of linking is a separate concern. There’s nothing stopping motivated devs from making every screen in an app linkable.

Hugh Guiney says:

I feel your pain. But, I question whether unimplemented codes are truly useful—otherwise they’d be implemented.

For instance, Google doesn’t really care about 410 vs. 404, so why should anyone else? What’s the benefit to specifying “how gone” a gone resource is? Seems like a pedantic distinction (and I say that as someone who has used 410s in practice).

Daniel Klingmann says:

@Hugh Guiney Usually a 404 should specify that a resource hasn’t even existed or can’t be found while a 410 at least informs you that the resource has existed at some point but has been deleted due to maybe a DMCA complaint or something else.

Benjamin Ragheb says:

Those of you taking the time to comment on this post regarding the merits of 410 Gone are completely missing the forest for a tree.

Ted Johnson says:

HTTP comprehension and usage are critical. People wonder why websites don’t perform and api are difficult to program for. I have seen that developers have this weird need to create your own method and means of communicating errors. Even ws-* developers don’t use soap errors. That is what we are talking about mostly in this article non-standard messages/state.

Treating your application and data as resources (REST is the style of the web) and leveraging the power of HTTP so powerful. You are not a crabby old man. If you do count me in, 33 years old. I could make a career consulting and only fixing http and resource abstraction/usage problems.

IMO though educating our fellow developers on HTTP is easy compared to the REST HATEOAS constraint.

Craig says:

Passive aggressive claptrap; didn’t read.

Thomas says:

GET is idempotent but it is much more than that, it is the identity. I think your confusion comes from the fact that PUT is idempotent (wich is the main difference with POST which is not).

Evan says:

Wow, loving how the person telling us how we’re all misusing HTTP can’t even manage to handle front page HN load, to be fair.

Rando says:

It would probably help if w3c would start releasing spec documents in human languages.

John Doe says:

“developers tend to think they can solve every problem, and they’re pretty sure that nothing good happened before they arrived on the scene.”

I don’t think that’s the only problem. I would also add that the majority of companies has neither time nor money for the good solution and doesn’t care much about good design of the software side of things. Of course that thinking does backfire in the long run but that doesn’t change the reality.

Ignas says:

Returning 200 status for everything is a bad practice that can mess up search engine indexing and cause confusion in general. However, I don’t think it’s that a big of a deal to return 404 instead of 410. Take for example a dynamic website, like this one, with serves some content based on the id in the url. Would it make sense to add extra code to somehow deduce that the content for that id was deleted just to show 410? No it would not. It is a lot easier to show 404 whether it was deleted or doesn’t exist.

That been said, I don’t think returning wrong status is as big of a deal as serving correct content. Not only pretty much every website out there serves invalid HTML code, but some also serve a ton of useless HTML, CSS, and JavaScript which does absolutely nothing. Not to mention the fact, that developers lately can’t write couple lines of code without resolving to big, slow, and clumsy frameworks. Seriously, you can write dynamic webpages without jQuery. Code will be faster and total size will be smaller. Did you knew that?

Natasha says:

The real problem here are the purists who think that their theoretical ideas actually work in practice. News to you guys, your ideas don’t work in the real world!

404 responses are a superb example of this.

Say I have a RESTful HTTP API, and a request to /user/3324/ will return details about a user with the ID 3324.

I want my API to satisfy the purists, so I have it return a 404 response when a request comes in for an unknown user ID.

Jamal, who is using my API, makes a typo in his code that constructs requests to the API. He accidentally has his code make a request to /users/3324/, instead of /user/3324/, and doesn’t catch his mistake right away.

My API returns a 404 response to Jamal’s request. Now here’s the problem Jamal runs into: is that 404 because he made a request to the wrong URL, or is it a 404 because the user doesn’t exist? He doesn’t know, and he can’t know.

Jamal comes to me with this very real problem. He’s says that this uncertainty is not acceptable, and he’s completely right.

So I do the sensible thing: I use HTTP response codes to indicate the success or failure of the HTTP response itself. And when a user isn’t found, I return a 200 OK response, and otherwise indicate that the user doesn’t exist within the response body.

Now the HTTP purists don’t like what I’ve done. But you know what? To hell with them! I’m living and working in the real world. My HTTP API is being used by people in the real world.

If the HTTP purists goofed and came up with technology that doesn’t work in important and frequent cases, I’m going to treat their mistake as a bug, even if they mistakenly believe it isn’t. And I’m going to work around the bug in their technology, even if that annoys them.

Until the purists get their crap together and do things right, those of us in the real world will just have to ignore them, or otherwise avoid their mistakes however we can.

  • Natasha

NickM says:

One reason some websites only send 200 responses, even when errors have occurred, is that when CORS requests receive a non 2XX response code, they have their response bodies stripped. It makes determining what error occurred difficult, if not impossible sometimes. So people reimplement HTTP error codes in XML/JSON/plain text!

Giacomo says:

Natasha @18 is a classic example of what OP illustrated. Natasha doesn’t know about 400 Bad Request, which is a perfectly legitimate response to an API call to the wrong endpoint (i.e. /users/ rather than /user/); or a 405 Method not allowed, which is also perfectly legitimate (the server does not allow a POST/GET to /users/). And in any case, you can always send a payload to explain that your 400 or 404 or 405 is an error because /users/ is not a valid endpoint, if you can’t be bothered to document it elsewhere.

Natasha is the typical example of developer who thinks he/she knows better than the people who built the technology he/she uses, except he/she really doesn’t.

SleeperSmith says:

Because a protocol for serving the web pages can be rammed into holes with any kind of shape even tho the peg is only round.

Get over it. HTTP is just for web developers who has problem understanding any other protocol.

AlsoGetOffMyLawn says:

Agreed, 100%. I would cynically add that HTTP2 is a symptom of the very disease you’re describing. 40 +/- years ago when HTTP was conceived, plain text was chosen for the signaling on the wire. Bytes were much, much, MUCH more precious then, and yet they chose to send headers, status codes, etc. in plaintext!

Why? Because it made debugging much simpler, and it made it possible to hand craft requests to a remote resource with nothing more than a console connection (and of course the ability to read the server’s response). It also allows for network monitoring tools to see that plaintext signaling. Google, and the standards body (bodies?) believe they know better than the people who wrote the underpinnings of possibly the most impotant protocol in the history of mankind. Binary signaling? BAD IDEA.

Natasha says:

My Dear Giacomo,

Your abusive use of those other response statuses just makes the situation worse that it already was!

400 Bad Request is such a general error so as to be useless. Returning that now leaves Jamal wondering which of a thousand different things might be wrong. That doesn’t help at all.

405 Method Not Allowed is also a poor choice. It also doesn’t indicate to Jamal what the real problem is. In fact, it misleads him into thinking the request type he made is the problem, when the real problem obviously involves the URL. That, too, doesn’t help at all.

And it’s ridiculous that you condemn the use of the payload to indicate what the real error is, only to turn around and suggest that the payload be used to indicate what the real problem is, because the HTTP status codes you recommend using are damn near useless!

If a payload is coming through, then as far as Jamal’s concerned the HTTP request was successful. The server received it, the server was able to process it to some extent, and the server was able to return a response.

You’ve gone out of your way to impede the API consumer solely for the sake of purity. Face it, HTTP status codes are nowhere near as useful as you and other purists claim they are. Your theoretical ideas about their practicality just don’t carry over into reality.

Error messages need to indicate without ambiguity and without uncertainty what went wrong. HTTP status codes only do a half-arsed job of this.

  • Natasha

cmurf says:

“Narcissism runs rampant in this industry, and our willingness to throw away and ignore some of the core philosophies of is just one manifestation of this.” This is a recurring theme, just pick an industry: Aviation had the Airbus automated cockpit which solved some very real problems but also discarded a lot of tried and true core philosophy, and now drones with “goddamnit the government sucks let me fly my f’n drone wherever I want”. Banking, “oh these rules from 50 years ago are bullshit and keeping me from making fucktons of money, gimme!” It is definitely the result of the bard variant of narcissism, I don’t know if these people as children were slapped too much, or not enough.

Sean says:


What is wrong with issuing a 404 with a response body? I mean, the spec expects that.

“The 4xx class of status code is intended for cases in which the client seems to have erred. Except when responding to a HEAD request, the server SHOULD include a representation containing an explanation of the error situation, and whether it is a temporary or permanent condition. These status codes are applicable to any request method. User agents SHOULD display any included representation to the user.”


You returning a 200 status code is wrong, and it has nothing to do with purism or anything else. You require your API consumers to do extra work to actually parse the response body when looking at the response header should be sufficient. There really isn’t an excuse for doing it the wrong way.

Visionscaper says:

Natasha, Interesting how you make the point of the author so clear! In your example (@18) you should use 400 Bad Request with an appropriate explanation in the body.

NoLand says:

Just my two cents on the 404 discussion (which is not that trivial as it may appear at first sight): I think, we need some kind of theory of types to resolve this. In detail, it’s about the relation of a URL and a resource. So what’s the resource? In the case of “GET /users/3324/” the ID is part of the path to the resource, so we may argue that the resource to which this URL is pointing to is not present, if there’s no user with ID “3324”. (Actually, it is of no importance to the client, whether the response is a representation of a static document in a directory, or if it is the output of a dynamic service.) Since the path is not pointing to a valid resource (be it static or virtual), we may consider a 404 or 410 as the correct response. In case we would specify the ID outside the path (in a query string), like in “GET /users?id=3324”, things are quite different, since the path is now pointing to the service “/user” itself. Since the service is to be found at the given path and presumingly working, we should return a 200 even in case that there is no user with ID 3324. In this case we’re actually wrapping a HTTP service around our own protocol and API errors should be handled inside the response body, since the error is not in the HTTP layer. On the other hand, if the service would be only accepting POST requests and would be addressed via GET, we would return a 405 all the same. (We might consider it to be a 400 Bad Request in case that none of the required parameters, like “id”, is supplied by the client. But we might, again, argue that the error is not in the HTTP layer and should be handled in the inner protocol of the response body, as long as the service is up and running.) So, what you should return depends on the path as a relation of a URL and a resource local to the host.

Giacomo says:

Natasha keeps validating what OP says. She doesn’t understand that the point is not “abusing the payload”, the point is using HTTP the way it was supposed to be used, i.e. semantically.

HTTP is not TCP, it’s not about getting packets from A to B; it’s about locating and interacting with remote resources. If you get an HTTP error the transmission was fine, what the server should return is a code related to resources exposed by such service. Believe me, “Jamal” will be much happier to get real error codes when things go wrong, so that he can parse the payload for errors only in a subset of cases, rather than having to read each and every payload to figure out if it’s been successful or not.

Deepak says:

HTTP is about reading documents (hyper text). We started building apps using HTTP. Should we feel sorry about that? Was it designed for building web apps?

Chris says:

410 Forest for trees not found.

I don’t think that forest is ever gonna come back, guys...

JimJim says:

This is some interesting discussion. I see several people saying that Natasha “doesn’t understand HTTP”, but I don’t think that’s the case. I just think that she has a practitioner’s understanding of it, while those who criticize her have the luxury of only needing an academic understanding of HTTP. It’s easy to buy into the REST hype, or to brush aside the problems she mentioned, until you actually have to build and/or use an API in practice. Then the issues that Natasha mentions do become very real, and the academic claims fall apart. When the approaches suggested by the academics fail to work in practice, as is usually the case, and when the academics don’t want to provide truly useful solutions, as we have seen in this discussion, then practitioners will have to take matters into their own hands. Unlike the academics, practitioners need to build systems that actually work. If throwing out the pure, yet impractical, ideas from academics allows working systems to be built, then the academics’ ideas will be thrown out. The academically-oriented commenters here need to realize that their solutions don’t work in practice, and they should look for practical solutions to the flaws in their work, rather than ridiculing practitioners who point out how flawed or broken or useless the academics’ ideas are when subjected to real-world constraints.

Christian says:

I was one of the earliest web hosts and web content developers on the internet, while working on the Multimedia Team at NASA/Ames. I was forehead-deep in the technology of the early web through the late 1990s.

Then I switched industries entirely, and didn’t give another thought to web dev for ~15 years.

Now I’m back. And feel like some sort of Jules Verne character, or something! I sit in meetings where people devise the complex tools/solutions to some sort of problem, and – after sitting there mystified for 15 minutes or so – I will ask the Stupid Question... “so... why don’t we just use X?”

Everyone will look at me blankly and say, “What? What’s that?” I’ll then bring up the RFC, or demo the error code, or whatever, and people in the room will say, “Hm. Wow. Never knew it did that.”

There is definitely a divide that has been created between the people who understand how the data flows work underneath (and how they are defined to work), and the people who push the pixels around at the presentation level.

Thanks for writing this out. I am definitely going to create a persistent link to this where my teammates can read it and remember it!

Natasha says:

My Dear Sean, Visionscraper, and Giacomo,

Why do you keep suggesting the faulty idea of using highly ambiguous 4xx HTTP status codes, even after I explained the problems with them to you?

Are you unable to comprehend the concept of unambiguous error codes?

Are you unable to comprehend that, because of the highly ambiguous nature of the HTTP status codes that you’re suggesting, the API consumer will have to check the response body no matter what the response is?

It is better to do away with almost all of HTTP’s half-arsed status codes and to come up with a custom scheme that isn’t so terribly broken and highly ambiguous.

You HTTPers have had over 20 years to get your broken status codes fixes. You have not managed to do so! So those of us getting real work done will work around your buggy status codes. Our work matters more than appeasing your sense of purity.

  • Natasha

Andrew says:

This is wonderful reading :D I can’t wait to consume yet another webservice that says 200 for every request, regardless of how malformed. Then I can study the custom reimplementation of error codes she has done, and manually parse it. Again. To hell with standard error handling in my HTTP clients and AJAX, I want yet another error code. Maybe I can even write a shim to convert it back. Perhaps our fine @18 can even make an RFC documenting these new JSON error codes and their meanings... you know, so we can have 2 standards that are ignored :D

Just define the semantics of your api. 400 is a bad requests (see response body for reason). 404 is the requested resource is syntactically valid, but no records was found. Or the other way. I don’t care... It shouldn’t take more than a few lines to “document” this, and all of my middleware will be happy. Hell, you can even call them both 404s for all I care, because it is usually an error I can’t recover from anyway.

William Greenly says:

URN’s are not a step above URL’s, URI’s are. URN’s and URL’s are mutually exclusive.

RFC 3986 is the spec for the URI. So all URL’s and URN’s are URI’s.

A URN is by definition, usually not dereferenceable, or has no standardised means to dereference, whereas a URL is.

Additionally, although your URL can be canonical, the W3C web architecture guidelines (along with ration and reason) strongly recommend that they should be opaque. So don’t think about attaching semantics to and identifier other than those specified in RFC1738 and RFC3986. The application semantics is determine when the resource is dereferenced, no by deriving additional semantics from the identifier. So do assument http://www.people.com/people/will to be a document or graph about a person just because the identifier(URL/URI) contains the word ‘people’, and don’t create a convention of semantics based on this anti-pattern. This applied not just to typing but also to classification axioms and any other semantics than those defined in the spec, because its sole purpose is as a identifier.

Sean says:


I’m sorry, but I do not understand your point. Your solution is to return a 200 with a description of the error. My solution is to return a 40x with a description of the error. Your solution requires that the consumer parse every single response body to check for an error condition. Mine allows the consumer to handle error conditions with status codes. I am unable to see the justification for your solution.


JimJim says:


I think that what Natasha is saying, and what I’ve experienced too, is that any real API will be able to fail in many different ways. Sometimes one type of failure could be caused by many different types of problems. So while a 4XX or a 5XX status code could be returned, it is not specific enough for the types of problems we see in practice. Any competent developer will end up having to process the payload of those error responses anyway to get the more specific error details, to figure out how to proceed. Academically-minded people such as yourself don’t seem to grasp that what you’re claiming just doesn’t hold true in practice. HTTP status codes are just too inflexible and limited and academic to be useful in practice. So practitioners need to do things properly, their own way, since the proposals from academically-minded people such as yourself just don’t work in practice.

Pat says:

@JimJim & Natasha Wow, your comments and ideas are just weird, it hurts. I am a practitioner and ... guess what... also an academic. Returning proper Http status code (instead of 200-OK + error-payload) on an actual error is the only reasonable thing to do. Have you ever been using modern frontend frameworks as emberjs before? Because it’s data module for syncing REST-based data would not be able to work properly / efficiently, if the framework cannot distinguish between non-existing, non-modified, non-existing data etc. Or a more trivial example: All popular Browser developer consoles mark non-ok requests in red, yellow,... which is super useful to catch unconscious errors.” and I could not imagine debugging without these features. Or can you imagine open up “dem 200 requests”, being paranoid there are eventual error data packed within? Hell no. 4XX and 5XX are supposed to be “generic”. It is a hint to read the error payload. It’s a standard! I love how you claim to have reallife experience and probably never have tried the way of >academics< to fortify your misleading claims. Or probably your statements are going over my head, because what I read from you just makes me wonder...

Augustin says:

There is no reason to get mad like that.

Who would think of copy-pasting a Gmail url to share an email content to someone? Not even your grandma.

Apps & websites have different use case.

Richard Stanford says:

Its also worth noting that many toolkits to consume REST services make getting at information in “error pages” harder than it should be. Sending a non-200 response with a body that needs to be decoded can move your service from simple to complicated.

One thing that I try to do is to encourage everyone to use HTTP errors very, very carefully. I end up interfacing with a lot of payments providers, for example, and they’re all over the map. If I send a directive to “Charge this card $200” then I’m fine with a 200-OK response coming back with a body that says, “Hey, everything worked absolutely perfectly, all parties communicated well, and the result of that transaction (which we’ve persisted in the database and everything) was that the card was declined.” That’s not an error anywhere near the transport layer, that’s purely a business-domain error.

In many frameworks, making a request that returns a 500- error is (IMO incorrectly) expected to start rolling things back like a request to a database that failed, and stopping that process can also be annoying. People who expose APIs should try to make them as friendly as possible, regardless of how silly the consumers might appear.

Spacemoses says:

Anyone who calls my resources knows very well that I am a teapot.

Giacomo says:

I love it how some people complain that 4xx error codes are “ambiguos”, then proceed to make 200 the most ambiguous of them all. What you are doing is basically just discarding all http error codes, saying “that’s transport layer, I don’t care, I’m all about business”; except it’s not true, because http has a plethora of codes for almost any case that is semantically significant at the business level, and if you think a code is ambiguous you can just attach a payload. Now clients can have a nice and clean “if OK: allgood()” bit followed by tons of error-handling special cases, whereas Natasha’s clients have “if OK: checkiferrorA() && checkiferror_b()” and so on and so forth, so basically your OK status is completely meaningless.

Anyway, i echo Christian in “feeling like Jules Verne”. We’ve had this exact debate 15 years ago with the REST vs SOAP battle. How many SOAP APIs do you use today? Do you enjoy developing against them? uh-uh.

Jonathan says:

Unfortunately, before Web Sockets, HTTP was essentially the only protocol code from the network could use to access anything outside the browser, and it was certainly well-tuned to the use case of delivering media in response to a human actor’s request. When all you have is a hammer and a job to do, the only good option is to cast everything to a nail and hope for the best...

The trouble is in the fallacy that everything exposed by HTTP ought to conform to the object model (and side-effects) of a media item as envisioned by HTTP. It’s not that HTTP’s status codes are too vague or too specific; it’s that HTTP has, by the happenstance of being good enough and in the right place at the right time, become a leading machine-to-machine transport protocol, well beyond the intended field of use for which its nomenclature was developed. And colonialism, which in the micro includes bourgeois hyper-normativity, is a liberal value, as long as it’s fun and fresh.

In other words, stop telling me how to properly drink my tea. I’ll give you a 200, a 400 and a 500. If you want more, go use Microsoft’s floating-point status codes and leave me out of it.