96 comments

[ 2.6 ms ] story [ 119 ms ] thread
I tend to agree. I have worked now with a few REST APIs and it seems none of them implemented REST well. Just adding verbs like "delete" or "get" to the URL feels better to me compared to using HTTP verbs.
(comment deleted)
I think this is a version of the right answer. I would love to see someone do a teardown of all of the Best in class REST interfaces. Because the reality is some of the systems that get pointed to as most robust and we'll designed generally all contain a place where they have heavily skewed from the standard.

All that being said I think REST is an architectural pattern that can bring some order to the chaos. And I have seen thought experiments experiments that embrace it's constraints bring significant performance enhancements to many a system.

I've worked with systems that use RESTish patterns purely for request pattern conformity, eschewing any of the auto-discovery portions. I've found that reliance on verbs for noun modification with some separate action verbs builds a system that is very clean to interact with but... it's all in the details, there are plenty of terrible RESTish systems out there and there are some wonderful systems built on alternate patterns (like XML RPC).

I think the one thing RESTish design can bring is a simplification to the communication layer, but if you're interacting with it through HTML forms then you'll need hacks to get it working in the first place (many HTTP verbs are not supported as methods by most browsers).

Basically, it's an additional tool with some value for organization, if you use it zealously you can waste years of labour building a perfectly RESTful system. Do what works for you.

> Well, it means that I can easily program all my web services to accept both GET and POST (normally without changing any of my server side code, to seamlessly accept either)

...unless you've got more params than can fit into the de facto URL length limits of browsers (~2K characters for Internet Explorer), in which case you're stuck with POST.

Or if the request has side effects, which GET requests are not supposed to per the HTTP RFCs.
RFCs are often useful guidelines, but don't get too hung up on them. There are always side effects. eg resource usage, interaction effects (cache priming), etc.

[Edit:] > The point is that GET is not supposed to change the information stored on the server side.

The RFCs for HTTP USAGE are guidelines that are less about utility and more of an interoperability dream that was never realized. There's nothing sancrosanct about them. There have been DECADES of usage contrary (eg medical, gamedev, advertising, ERP, etc). At some point people realize it's bikeshedding issue that's more trouble than it's worth.

> There are always side effects. eg resource usage, interaction effects (cache priming), etc.

"Side effects" probably isn't the best term for what I meant. The point is that GET is not supposed to change the information stored on the server side.

I'm not sure what upset this Mr. Graffittis so much, but he seems to be excessively angry with HTTP verbs . Anyway, thousands of developers have found ways around this problem. Here is one:

Most people use GET for retrieval, POST to change system state and DELETE to delete an object. You might go crazy and experiment with PUT, or not, your choice.

As a team, you can establish some easy rules too (e.g. is it books/1 or books/book/1 to query a single book?).

Sure, REST is not going to answer every problem, but no standard ever does. Standards are meant as guidelines (esp. those related to naming conventions like REST). Have fun with it. Stop the hate.

You can really implement anything under any verb... Given the flexibility of http as a standard.

I have always hoped to some day stumble across some madlad who scales a large production system on the back of DELETE

Although sadly browsers are starting to enforce the behaviors of verbs more and more...

Someone hurry up and get coding

not nearly as bad, but I've worked at a company that tried really hard to be as pure REST as possible, closely following the http semantics for everything... except they used POST for idempotent actions and PUT for the non-idempotent ones.

That was....confusing on my first week.

How'd they manage the fuck that up so badly?
Was pretty funny when we argued it. I explained http verbs to them after being told it was "THE REST STANDARD (TM)", and when I linked to them the http verb definitions, the reply I got was "Oh, I guess they must have changed them since last year, huh?"

I can't make this shit up if I tried.

Having non-idempotent API endpoints in the first place is a bad idea. It might be unavoidable, if that endpoint directly controls some non-idempotent real world action that can't be managed with transaction ID's or the like, but an API endpoint being non-idempotent means that if there is ever a poorly-timed moment of service or network unavailability and you don't receive a healthy response from that API call, you have to be prepared to either completely drop whatever you were trying to do in the first place or accept the risk that it'll happen twice.

At the risk of making an overly broad and offensive comment: amateurs discuss standards and semantics, professionals discuss resiliency and requirements.

How would you do a endpoint that creates, for example, a new resource? Like, if I have a todo list and I want 2 todo items with the same text. My create todo endpoint will have to be non-idempotent. That's what the semantics of a POST is for.
Generate a UUID on the client side and pass it as a parameter, and configure the server not to process the same UUID twice.

Though if it’s just a todo app, it probably doesn’t matter. It matters slightly more when the resources you’re creating are things like “purchase orders” or “payments” or “shipments” or “hailing an Uber”.

It isn't prevented but... it's like developing in an esoteric language, if your language interpreted any inequality as a test if the left hand value is lesser than the right hand value (i.e. 2 < 3 equivalent to 2 > 3, both are true) you _can_ work within it, but why bother. Use the common language constructs and design paradigms other people do unless you enjoy making it hellishly difficult to train up new people.
So browsers have started to do a lot of rewrite on the periferal verbs.

Grab XMLHttpRequest and start returning different content types in the header and body. Depending what browser you are in you will start to see things go inconsistently sideways compared to the same actions on get or post

(disclaimer: TFA is dead for me right now so I might be speaking out of context)

REST (like "object-oriented programming") is an ambiguous term that might refer to a reasonable and usable subset of behavior, or it might refer to a more extensive hypermedia-style design pattern.

REST, in the hypermedia sense, and in the sense of "the design principles behind HTTP in the first place", is a good way for a server to expose data to an intelligent human-guided client (i.e. a web browser). It doesn't do a lot for the API case, but it does a little and there's enough tooling to get you the rest of the way.

I usually don't even think of REST API's as RESTful. I think of them as RPCs that exchange JSON, except you define the RPC endpoint as an HTTP verb/URL pattern tuple, accept and treat as a contract the standards behind different verbs, use response codes for out-of-band metadata, and piggyback on all the tooling and infrastructure that people already built around serving HTTP to web browsers in the first place. If you want to strongly type your RPC, you can use OpenAPI. If you want to define your RPC ahead of time and then generate server and/or client code from a definition, you can use Swagger Codegen. There's enough adequate tooling that you don't necessarily need to resort to an actual RPC protocol, but that doesn't mean your REST API actually has to be RESTful in any meaningful way, or even that it should be.

> is a good way for a server to expose data to an intelligent human-guided client (i.e. a web browser)

A web-browser doesn't have any concept of REST; it only provides a sandbox for the client code which knows how to map paths to data (but pretty much never does so by means of any sort of introspection). Note that this isn't advocating against REST or in favor of RPC, just a neutral observation.

(comment deleted)
Actually the original, core, really REST thing (that almost no one views as REST anymore) is all about resource exposure, and a dumb browser doesn't know how to interact with it but a REST aware generic browser could potentially interact with RESTful endpoints without other assistance.

I'm specifically talking about the portion of rest that includes delivering actions with noun results, i.e. "Here's you comment record, if you want to edit it go to this URL, if you want to delete it here's a different one".

Also, I, personally, find that portion of REST to be silly. I like the organizational hints and guidelines, but the resource discovery seems far too pipe-dreamy to ever be built on a large scale.

> I'm specifically talking about the portion of rest that includes delivering actions with noun results, i.e. "Here's you comment record, if you want to edit it go to this URL, if you want to delete it here's a different one".

How does that not describe a normal HTML page that has "edit" and "delete" links right next to the newly-created comment that it displays to you after you click the "reply" button on Hacker News?

I mean, it's not automatic discovery, because you're relying on a human being to read a rendered web page and know what the links mean, but it kind of qualifies if you expect that the client is partially made of meat.

That's sort of the point, it was to remove the meat requirement on discovering those. Making the edit/delete/whatever forms and requirements machine readable so a stronger but still generic client tool can interpret them more intelligently.

Again, I think it's naive since while a lot of stuff has plain CRUD operations, there are entities in most webapps that have more complex operations. If I were writing an application that partially managed cutlery in a restaurant it's not clear where a "clean" verb on a fork would fit into REST and how a generic client would understand what significance "clean" has especially as it relates to future eat actions.

I have read through and understand the intent of the original RESTful system and I think there are some good and bad points. But, automatic discovery was definitely included in their vision of how it'd work, and actually seems like the center point TBH.

> That's sort of the point, it was to remove the meat requirement on discovering those. Making the edit/delete/whatever forms and requirements machine readable so a stronger but still generic client tool can interpret them more intelligently.

Hmm, that makes REST sound like it's pursuing similar ideas as the Semantic Web.

> Again, I think it's naive since while a lot of stuff has plain CRUD operations, there are entities in most webapps that have more complex operations. If I were writing an application that partially managed cutlery in a restaurant it's not clear where a "clean" verb on a fork would fit into REST and how a generic client would understand what significance "clean" has especially as it relates to future eat actions.

It isn't clear at all. It's possible, but in weird, hacky ways. Maybe when you're done with a fork, you DELETE the fork and then you can POST to /clean_forks/ to create a newly cleaned fork. And if you run out of forks to clean, it throws a 503 error. It's a terrible Kingdom of Nouns (https://steve-yegge.blogspot.com/2006/03/execution-in-kingdo...) but it might appeal to some people, for the same reasons that the original Kingdom of Nouns appealed to some people. After all, you get to feel clever and smart when you invent new design patterns to work around the limitations of your technology. Just writing a `clean_fork` RPC doesn't make you feel clever at all.

In any case, while I can see automatic discovery as a useful feature for web browsers (who can still punt the actual decision-making to the meat, as long as they know what the plausible next steps would be), it doesn't seem likely to me that service clients would benefit from it any more than they benefit from a thoughtfully designed and documented RPC API. Meanwhile, for whatever reason, the end-user-facing web has decided to prioritize the use case of, "you will see and interact this web page according to The Original Creative Intention Of The Author" over the use case of, "here, have some data, it links together, do whatever the hell you want with it, I don't care what fonts or UI widgets you use". REST would have been great for the second use case; it's just that nobody cares about it anymore.

> Hmm, that makes REST sound like it's pursuing similar ideas as the Semantic Web.

One of the founding principles of REST is that links should be discoverable and resources should include the semantics of each link that's directly accessible from them.

https://en.wikipedia.org/wiki/HATEOAS

Your "fork" resource simply need to include a hyperlink to the cleaned self. Its no different then obtaining a "clean" page on the web, with the forms emptied, etc...

<fork> <a rel="clean_fork" href="http://example.com/very_clean_fork" /> </fork>

Indeed, and what does `clean_fork` mean? I don't disagree that it has some value, defining associated actions for the resources being served, I was more questioning how universal this approach could ever be.

And bear in mind `<a rel="clean" href="http://example.com/database/clean">` would have a very different semantic meaning from `<a rel="clean href="http://example.com/fork/clean">` or what have you.

I agree that semantic actions are a thing it'd be nice to solve and I wanted to make sure this discussion on REST touched on the fact that semantic actions are something they tried to solve. But they didn't, we've assigned common meaning to common verbs (which is pretty sweet on its own) but everything else isn't discoverable.

If you were a rather dumb client interface and got a `<a rel="clean_fork">` what would you do with that inherently except say "It isn't delete or put or patch, so I don't know what this does"

Media-types and their semantic were always supposed to be sideband information, just as the meaning of <a> and <form> is documented in HTML.

An easy way to think of it is that a Web Browser is a client for a REST architecture consisting of the web. If you create a new system and use a REST architectural style, the client app(s) will be the "browsers" for your API.

When you implement a web browser, you do need to receive sideband information about the media-type (HTML) and your client application has to be able to understand those, including what <a> and <form> mean, for example.

In a custom API, you use the same HTTP verbs if you want (REST doesn't mandate HTTP) but you need to define your media-types.

I thought the general idea is to code the client against a well defined and sanctioned media type. If the media type returns items and actions, a well coded client should be able to handle it (whether it is to show it as GUI and provide controls or do some automated response etc). The point of returning actions is that URLs change, and must be able to change. Instead of following HATEOAS guidelines, people hardcode routes and lament about how URLs should be structured (flat vs nested, e.g. `/posts/1/commment/4` vs `/comments/4`) and then they also have to be versioned etc. (`api/v2/posts`). Now that is silly.
> If the media type returns items and actions, a well coded client should be able to handle it (whether it is to show it as GUI and provide controls or do some automated response etc).

In a web service context, is there a HATEOAS web client library that I can use to make service calls without having to specify endpoints and request formats ahead of time?

> Instead of following HATEOAS guidelines, people hardcode routes...and then they also have to be versioned etc. (`api/v2/posts`).

In the web service use case, it's considerably simpler to define and specify a set number of endpoints ahead of time, define request and response formats, document that specification in OpenAPI, and use versioning if the API itself changes. This isn't RESTful. It's just RPC over HTTP. But it works and it's not "silly".

> Also, I, personally, find that portion of REST to be silly. I like the organizational hints and guidelines, but the resource discovery seems far too pipe-dreamy to ever be built on a large scale.

The amount of work really isn't that great when compared with having to layout routes.

Proper HATEOAS is like unit testing: people complain it takes too much work but then complain that the lack of tests is a problem.

> REST (like "object-oriented programming") is an ambiguous term

It really isn't. There's a whole doctoral thesis describing in detail what REST is and what it is supposed to achieve.

A thesis that we are all welcome to ignore. REST means exactly what we (collectively) decide it means. Sorry if this bugs the pedants in our midst, but no one really cares too much that they are using REST 'the wrong way' when it is just another tool to be used to get the job done.
> A thesis that we are all welcome to ignore.

That just means that ignorance is leading clueless developers to misrepresent a specific concept by talking about stuff they know nothing about.

Not knowing something is not the same as something not existing.

REST is exactly what Roy Fielding defined it as, in https://www.ics.uci.edu/~fielding/pubs/dissertation/top.htm. Anyone is welcome to do something different, but similar. However, in the name of sanity, don't call it REST/REST-like/REST-ful/etc. Instead, give it a new name and say it is based on (or derived from REST). Give credit where due, but have the courage to name it a new thing. Like SOA, and Agile, REST has had a proliferation of APIs claiming to be REST or RESTful, when they are not. To do otherwise is all of: an insult to Dr. Fielding, a muddying of the term REST, a disservice to the developers using your API, and a disservice to yourself (because you have created something new).
Speak for yourself.
While true, enough people misuse the term "REST" that you can't trust, upon seeing the term "REST", that someone is actually talking about Fielding's ideas. Unambiguous terms become ambiguous if enough people are sloppy with their usage. I wish it wasn't so, and perhaps you can have a personal crusade of correcting everybody who says "REST" when they really mean "HTTP API that doesn't use SOAP and seems to respect verbs and response codes", but much like the terms "ironic" and "to beg the question", "REST" has been poisoned by sloppy usage.
> but much like the terms "ironic" and "to beg the question", "REST" has been poisoned by sloppy usage.

This problem is not caused by sloppy language but by militant ignorance of such a level that leads clueless people to assert that a concept has not been defined when that's patently and painfully false.

Invective aside, when someone you don’t know uses the term REST, can you reliably guess what they actually mean by it? You can’t, and that’s the definition of ambiguous.
What about PATCH?

I personally like PUT even for delta updates, but a dev I was working with was obsessed with wanting PATCH.

I like put for updates and patch for partial updates (but without the command/diff structure - only fields that are provided are patches)
Your colleague was right: put is for total object replacement and patch is for partial object update. The guiding principle is:

* POST: create new object, including their primary keys. Run appropriate sanity checks.

* PUT: extract old entity object and update all attributes and dependencies, possibly deleting and regenerating all dependencies while preserving the object's keys.

* PATCH: extract old entity object and update a small subset of its attributes. Run sanity checks that are specific to this form of update, and avoid touching bits in the persistence layer that are not linked with the update.

Put is very important because total entity replacements really don't replace the role of partial updates, particularly if we consider how extensive transactions can become.

Yes, I know he's right technically, but I've never seen it in any popular APIs.

Unless, of course, I am mistaken.

Yes you do have a point. Even the OData standard specifies that PUT is the catch-all verb for entity updates, although there is a hefty discussion on introducing PATCH.
We've been implementing PATCH operation using PUT. If a certain properties in not undefined, we update it, otherwise we don't.
i use them this way:

PUT: create new object at a known location. object need not exist. if it does, it is replaced.

PATCH: change an object.

POST: send arbitrary data to an object. this may or may not lead to the creation of a new object at another location.

Personally I think GraphQL's existence, while seemingly blatantly obvious in retrospect, is was what REST should have been. It lets "generic" applications to discover the API and its associated operations. Essentially its also simply a re-do of what Swagger (and a few others) attempted to do, but never really made REST work (imho).

Here's a good analogy:

Graphql is docker, REST is LXC.

Might be more accurate to say that SOAP is LXC and GraphQL is docker.
So one is user configurable and understandable (leaves much to the user) and the other is a black box that performs magic? One takes some time to understand and make work while the other just does the right thing 85% of the time?
> As a team, you can establish some easy rules too (e.g. is it books/1 or books/book/1 to query a single book?).

That's the thing about REST; you don't need any rules about what paths look like, because you shouldn't be constructing them manually. You get them from the State that was Transferred to you.

>I'm not sure what upset this Mr. Graffittis so much, but he seems to be excessively angry with HTTP verbs

One thing that upsets me is pop psychology and second guessing of emotions (about "being upset", "excessively angry", etc) instead of arguments.

>Have fun with it.

Engineering is not about having arbitrary fun with whatever "standard" we are given.

RPC is the way to live
Does this mean POST for every request?
It can, but doesn't even have to be done via HTTP.
Not for me; I'm willing to use GET for an RPC that's more GET-ey and DELETE for an RPC that's more DELETE-ey.
(comment deleted)
(comment deleted)
(comment deleted)
`We went from Procedural Programming, to Object Oriented Programming, to Functional Programming`

I mean, it's not really a progression; even inside of OO and Procedural there are a lot of differences and it's not like any of those are better than the other, they just allow you to write code that does the same thing in different ways.

"You know they try to eat non-mushy peas balanced on the backs of their forks!" Is that true? Why would anyone do that?
I'd love to hear from the folks at Slack to see how their initial API design decisions scaled. Their model is pretty clean and I really like the look and feel of it, aesthetically at least it's RPC-ish.

Part of the challenge when people have arguments like this is that they aren't experiencing the trade-offs in the other directions they'd like to go, so it would be great to hear the concerns about an RPC alternative which restricts the HTTP verbs to GET & POST.

It sucks because it's not a spec, that's all. HTTP is, GraphQL is. When implementing GraphQL either you follow the spec or it is not GraphQL. Same for HTTP. An vague idea shouldn't be the basis for architectural choices and I'm glad REST and its legacy are now criticized and contested.
(comment deleted)
I've found it's best to let other organizations be the guinea pigs and get the kinks out, or disprove it, before our own org adopts it. Too many get carried away with "new ideas" and dive in the deep-end blindfolded. Let it run "five years in a similar organization" is my time-proven rule of thumb. Unfortunately, I lack rank to enforce this rule.
I assume your criticism applies to OO? Or functional programming? Or event sourcing? Or any number of programming concepts without a "standard"?
> I assume your criticism applies to OO? Or functional programming? Or event sourcing? Or any number of programming concepts without a "standard"?

Don't assume anything, I never talked about OO, or functional programming, or event sourcing or any number of programming concepts without a "standard". Don't make up things in an attempt to further whatever point you are trying to make here. I never talked about those things and don't care about them.

Main problem is that most of the frameworks out there are REST / noun based, because it's easier to scaffold. Are there any that are more rpc/post/verb based out of the box?
Basically any HTTP microframework that has a minimum of ceremony between "declare HTTP URL endpoint" and "write function that handles requests to that endpoint". Flask, Sinatra, anything like that.

Or, you could use swagger-codegen and generate your service from a handwritten OpenAPI spec.

Basically agree, but was thinking more about something with a scaffold that specifically guides users toward a separation of actions and nouns, not just an indifference.
swagger-codegen kind of does that, with the tradeoff of making you define your API contract ahead of time.
PostgREST will generate a swagger spec for you from a database schema.
This seems like an... unnecessarily angry... bit of a rant.

BUT, I tend to agree. Just use GET for all requests that don't change things, and POST for those that do (important so spiders and pre-caching don't inadvertently take actions), and put everything else (including what the real verb is) in the URL or parameters.

The idea of trying to shoehorn your logic into additional PUT and DELETE verbs is unnecessary and makes it harder to use/support (e.g. HTTP forms don't support those verbs).

And... that's it. Fortunately I've never had to work with a die-hard REST evangelist, so maybe I've never had to feel the anger or frustration this post must be coming from...

looks like the site's being hugged to death.

nevertheless, i've had many annoying situations where i want to GET a specific list of ids, eg. /orders?ids=1235678,abcdefg and quickly run into the 2048 char limit, forcing me to design the API as a POST in all cases. combine that with additional sorting, grouping and filtering params and you're stuck.

the fact that GET is conflated with the url and has no body to pass params in is very limiting. at that point, HTTP verbs become mostly pointless.

When do you need to get a list like that where they couldn’t be collectively addressed by some other resource identifier? If we treat our “REST APIs” as generic database interfaces instead of equipping them with more semantics, of course we hit that wall.
if a user selects a bunch of options and records in the interface and then wants to pull an aggregate report on specific items which would translate into some AND id IN (...).

what if you need to delete a bunch of specific records in a single HTTP request with REST? you're fucked. DELETE is designed to deal with one record at a time [1]. sure, DELETE could have a body, but the recommendation is to ignore it [2].

to operate on multiple specific records, you're stuck doing at least 2 requests. a POST that asks the server to create some temporary "collection" record. and then use the new URI of that collection to perform more operations. why do all this overhead when you can just do the delete operation with a POST request and a body filled with record ids?

i could continue, but it should be obvious that REST was designed with the server as the center of the universe. when trying to shoehorn this worldview into modern fat clients and high-perf SPAs, it very quickly falls down.

[1] https://www.restapitutorial.com/lessons/httpmethods.html#del...

[2] https://stackoverflow.com/questions/299628/is-an-entity-body...

I don't think POST-ing to a /delete-records resource goes against REST, the original one, not the “common” one.
That's an interesting idea I hadn't ever thought of. But would such an endpoint return anything meaningful on a GET request? Would it return a list of all deleted records?
It becomes more clear to me in the context of api versioning. You rev the action, not the data. REST versioning makes it look like like you're versioning the data. Sure you can explain it away, but it smells not right.
Using GraphQL somehow lead me to not worrying about all that low level REST stuff anymore.

I define my schema, sprinkle some directives and push it to AppSync.

REST sucks because there're many ways to do something. Consider RPC, if you want to do something, you make an endpoint /doSomething, that's all, no need to mess around with combination of [http methods][noun(s)]([business method])
the worst thing about REST is that nobody agrees on what it is...

otherwise it's pretty fine, you just need to find a good server-side framework with proper tooling (springfox for java, nest.js for node) so that you don't need to write documentation (and test-console) yourself

graphql is great if all what you want to do is to publish some data but once you need more updates or predictable performance, it's not so easy anymore, and this is not just my opinion

Nobody except Roy Fielding.
Obligatory link to Fielding’s nearly decade-old blog post, “It is okay to use POST”:

https://roy.gbiv.com/untangled/2009/it-is-okay-to-use-post

The ‘recall’ and ‘sendpromotion’ ‘actions’ are still resources: ‘the resource that does a recall’ and ‘the resource that sends a promotion.’ You don’t ‘GET’ them or ‘DELETE’ them or ‘PUT’ something in their place. You just send a request that triggers those resources to do their thing: ‘POST’. It’s not CRUD and it’s 100% valid.

Its because his website sucks
Not to be too snarky, but this is just another "I did REST poorly and it didn't work very well, so I guess REST sucks" post.

Most of the other gripes have been responded to, but I wanted to add a comment about the "stateless" part: Its not that your Application is stateless, its the HTTP protocol itself that is. It is a contrast to other contemporary protocols like FTP or SMTP, in which you establish a connection and then perform "Commands", the order of which matters. In FTP, if you do:

    CONNECT ftp.example
    CD public
    GET myfile.jpg
The `CD` command in Line 2 changes the behavior of the `GET` in Line 3. This different from HTTP in that each request is independent of any others. The "state" is that the FTP server has to "remember" the current working directory of each connected client. If there were need for a high-availability load-balanced FTP provider that could support tens or hundreds of thousands of simultaneous connections, it would be pretty difficult because you'd have to maintain that state across all the servers. On the other hand, the stateless nature of HTTP means we can have Proxies and Load Balancers and CDNs all over the planet, and it mostly just works.
So are session cookies allowed?
The author's main beef in this article are the more exotic HTTP verbs. I don't think that gets at the crux of why REST sucks for Web Services/APIs.

The core problem is that REST (which, recall is a description of the web architecture) requires HATEOAS. JSON doesn't naturally implement a hypertext in the way that HTML does and, further, the other end of a JSON call is almost certainly code, rather than a human, and thus isn't able to take advantage of this feature anyway.

Here are a few articles on this general idea:

http://intercoolerjs.org/2016/01/18/rescuing-rest.html

http://intercoolerjs.org/2016/05/08/hatoeas-is-for-humans.ht...

I've designed and implemented a few REST api over the years that both made use of json for resource representations and also used hyperlinks. You do need to create your own media types and document them properly though, but media types and relations are at the core of any good REST APIs.
I'm not trying to go out of my way to be snarky... BUT I find it funny that someone writing about why a technology sucks; can't manage to keep their blog online.

REST is simple, simple is good. It's not perfect for everything, but it has served my purposes well for many years.

I hate it when people criticizes something they do not understand properly in the first place... Is it so hard to read Roy's thesis and do some proper research?
Article doesn't loads for me. Whatever is said, the answer is simple. REST was meant to be used by other applications in a not yet known way, and many where claiming REST is a "best practice" for API of YOUR single page application. It led to doing the same thing in a huge scope twice - selecting, modelling, and preparing for view of data, maybe even more. So we didn't use the context of the query which already shapes the data. GraphQL does. But GraphQL sucks in other way - as it adds unnecessary querying language (which already exists on the backend and it's for sure more powerful), and it makes a query on the frontend which is a security issue (which you can limit on the backend, but it's just a consequence of this mistake and still leaky).