25 comments

[ 3.9 ms ] story [ 70.4 ms ] thread
What a strange article. A browser does care if it is a GET or a PUT. The behaviour is different and IIRC defined in an RFC. The article limits itself about APIs, but some of the statements that are made are not correct. I guess a case of saying something wrong to trigger someone to educate you?
That's an odd response. If you think some of the arguments of the article were made poorly, point them out and say why. The source article seems pretty cogent to me; largely being an argument for not using REST for APIs, your comment about browsers seems misplaced.
See existing discussion of the article from 20h ago: https://news.ycombinator.com/item?id=9138700

The problem with

> If you think some of the arguments of the article were made poorly, point them out and say why.

Is that the linked article is fractally wrong. It's not so much that it has bad arguments, it's that there's more or less nothing which is correct in the article, and trying to reply to a specific incorrect statement only brings more incorrections, recursively, ending up with a tentative response which is longer than the original post by an order of magnitude.

The core issues are these: the author has no understanding whatsoever of REST (which I guess they can hardly be faulted for, since few people care to understand it), and is reinventing RPC-over-HTTP (badly and apparently with no awareness that it already exists).

It's kind-of a shame that you're not allowed to do an HTTP GET with a body.
Except you are. Some broken proxy may wreck your request, and your HTTP API may or may not allow it, but having a body in an HTTP GET is perfectly valid, as noted multiple times when this article first made the rounds 20 hours ago: https://news.ycombinator.com/item?id=9138700
You are not allowed to do an HTTP GET with a meaningful body. Happy?
You are allowed them but the body should not influence the outcome of the request. This is mandated by the HTTP/1.1 spec.
It's nice with urls without "&" when curl'ing from bash.
The point of REST is to reduce barrier to entry for using your API.

There is a specification for web requests which works rather well, is relatively applicable for any resource oriented service, and has well defined semantic conventions/specifications for failures, operations on resources, and responses to operations. It's an incredibly well known & understood specification. Any things you wonder have almost certainly been asked a thousand times before, and a single Google search will invariably land you on Stack Overflow with a productive discussion about what the best approach is.

Why not make use of this? You lose nothing by generally following the standard (since you can deviate from them whenever you need), but you gain so much - both from the perspective of building your API, and from the perspective of a potential person using your API.

---

Also two things specifically came to mind to mention:

> Who Cares about GET vs. POST?

There are very practical implications from the use of GET/POST. Any GET request you support can be called from any website without any knowledge from the user. For example:

  <img style="display:none" src="https://example.com/user/setPassword?password=foobar" />
By using a POST, along with standard cross origin protections, it is much more difficult for a malicious website to have any impact on your user. (Although CSRF checking should be done anyway)

"Well then, I'll just use POST for everything", you might say. There are a great number of downsides for that also: preventing caching, not allowing cross-origin communication without CORS, clients not being sure about idempotency, etc.

---

> "If we put the function name between the parameters themselves"

I found this interesting, because there is a language which does this - Objective C.

These are fairly equivalent:

  GET /customer/getOrder?customerID=33245&orderID=8769
  
  customerGetOrder(33245, 8769)
And these are equivalent, but oriented the 'RESTful' way:

  GET /customer/33245/order/8769
  
  [self getOrder:8769 forCustomer:33245];
  
  Customer.find(33245).orders.find(8769);
Personally I think the latter examples work much better in a resource oriented service. They show logical structure, relationship between objects, etc.
The headline makes me think of NoSQL. The NoSQL (poor nomenclature) movement came about because of limitations with decades-old SQL. I don't think such problems exist with REST, which is still fairly young.

More importantly, REST created a relatively clean and clear API that almost anyone can understand for any service. Sure, it does vary, as it is not "standard", and every site has their own resources and paths, but the learning curve to a new API is dramatically lower.

What are some popular APIs that are truly REST? AWS isn't. Twilio isn't (extensions to indicate formatting (and the URLs are built on the client, instead of using hypermedia)). They seem to be doing just fine. And I still cannot see, for instance, how having POST /deleteAccount is so much less understandable or usable than DELETE <URL discovered through previous use of API>.

As far as ease of use I certainly don't find it any easier to write clients that need to put parameters in the URL, headers, and in the body. And I've still gotta look at the documentation and most likely write a small client wrapper in most cases.

Elasticsearch comes to mind, and actually, REST has only hurt my use of it, because simple typos that would cause errors otherwise now have meaning. Eg DELETE /index/type/id when id is empty deletes a whole type. Whereas with RPCish, I'd be calling a "deleteDocument" method so no id just means failure. Also, it's lots of fun when your document id doesn't encode well into the URL, like containing / or must-encode chars. So again, what's the benefit I'm gaining here?

HTTP is fantastic cause it gives apps an easy client server wrapper for making TCP requests, along with some usable spots for request info and metadata. And as a bonus, GET vs POST lets us indicate a call might be read-only. Cramming APIs into some guys thesis on how HTTP should be used seems as weird as people that enjoy needlessly applying OO patterns to code.

The benefit is not (necessarily) that these ways of doing things are inherently better; it's that they are commonly used.

If you do things in this manner, everyone who has to deal with your API will have a good understanding of how it works. Even people who've never studied REST will have a good idea of how it works, as long as they are familiar with the web in general.

Hm this was the predominant way things were done about 10 years ago, and I think many people decided it ended up being harder to read.

Take this to its logical conclusion, and you end up with "http://mywebsite/getUserProfileFirstAddress" when you want an endpoint that just returns the first address (or you end up with lots of stuff in a query string that ends up becoming a quasi-programming language), as opposed to a "restful" way of doing it, "user/1/profile/address/1". It's not so much about being readable for computers, we can solve that problem, it's about being readable for humans, which is the harder problem to solve.

But REST is not about human readable APIs at all! You're supposed to get those URLs via hypermedia, right?

Your comment is great though. That's all people really want when they say REST (most people, anyways). It's codeword for "please don't use SOAP or otherwise make your API extra hard to use".

Ha yeah sheesh hypermedia... can I get a hypercard over that?

Anecdotally though - I find "restful" APIs much easier to parse and comprehend by eye than the old SOAP/Contract method.

> And these ‘simple’ URLs can be a pain when you want to extend them with more parameters, or even use more complex types like an array as a parameter.

Except in REST, a resource would not be identified by an array. If the resources would be a list and you would want to filter it, you would indeed use query parameters.

I do not see that the article brings up valid concerns at all. It seems to me, that the author just wants to simplify something, which is already quite nice and simple.

REST is a common standard, that fits nicely on top of HTTP. Why not use standard error codes if they are already available and commonly known? Isn't that the whole point about standards, that people know them and are therefore already better informed without knowing your specific implementation?

I understand criticism against religiously following standards when they are hard to implement or the benefit is marginal. I for example get, using cookies for authentication of an internal API.

I don't see the point of restricting myself to POST and 200/500 error codes, the extra work here to conform to REST is minimal while the benefit to the consumer is clear.

Because the HTTP error codes simply don't cover the errors of actual applications? So you end up returning the real error code in the body anyways. Now client apps need to check two different places for errors. (For instance, what's the error for "request can be completed but not with the price restriction you've set on your account" vs " request can be completed, but not for the price we've committed to", and "request cannot be completed because we don't have any available prices". That's three real errors we had to return over SIP, which takes the HTTP error model. You know what everyone does applying to billions of calls per day? Send back 503 on basically everything, except busy which happens to have it's own useful code.
What about 402 or 409? But that was not really what I meant. In your case, it does not cost the API-owner anything to use 503 instead of 500, he has to provide an additional message anyway. If instead a more common error occurs, it is just nice for the client to get a standard status code, that is known by frameworks and libraries and can potentially already be handled at that level. Just because something can not be standardized entirely does not mean you should not standardize parts of it.
The problem is that with the REST standard there are a lot of edge cases that are not commonly used. REST advocates cannot claim that no one is using REST "properly" and at the same time say that REST should be used because it is so common. Take the Dropbox debate, one prominent post featured on HN said that they should use a PATCH request type, which is very rarely used (outside I think certain version control systems). I imagine plenty of developers who want to use Dropbox's API have not heard of a PATCH request type.

So yes informal sloppy REST is commonly used and there is some virtue in that, but as any REST advocate will attest to, sloppy informal REST has its drawbacks, as Dropbox found out. Moving to a more formal REST architecture may solve those problems, but you lose the "commonly-used" virtue.

Add to that the problem that when you have application logic that is not REST-like, forcing it into REST can require a convoluted middle-layer. Avoiding that complication is worth well more than "commonly-used"

I like REST in general, and I even think formal REST with its many HTTP verbs and HTTP headers has a formal elegance. But there are plenty of reasons to go in a different direction, if your application logic favors a different way.

Thing is, REST isn't a standard. It's a general set of practices. While many people (myself included) strongly advocate putting a lot of effort into finding the "REST way" for your particular use case, you can deviate from it at any time without concern. Not all or nothing.
What I take from the article is that we try to push things into where they don't really fit. I like the modern URLs we are building now, that they are easy to understand to humans. The problem is not wether we should use GET or POST, the problem is when we try to use PUT and other verbs for things they are not ment to do. If you want a system to perform an action, it's not GET or POST, but it's not PUT either. You can't use the old HTTP error codes for application errors such as "flight is overbooked."
What I think many people are missing is this: there’s stuff that can and should be done in a RESTful way, mainly when you have a resource oriented api. On the other hand there is obviously cases where you really want to do RPC. There is no conflict, use RPC when you want to, but please do it according to some standard, without cooking up cool new URL structures.

JSONRPC can save you a lot of headaches, and hardly imposes any restrictions on how you roll your api itself.

Sounds like he wants Web Services with json. If he just comes up with a name other than REST he can use it for anything he wants, it would be silly to use the name for something where you clearly break all the rules/guidelines. And I don't get how it settles all discussions. Someone might still prefer the status code 400 over 500. And someone will want XML in the data instead of json etc. I will just say that I don't see any direct benefit with this.