Hacker News new | ask | show | jobs
by jillesvangurp 2899 days ago
Until AJAX happened around 2005, GET and POST were the only verbs you could actually use in a browser. Before then, REST was not a really a thing. It used to be that semantics of HTTP verbs had meaning in the context of e.g. caching and other middleware. But now that everybody uses TLS, having caching proxies acting as middlemen and interpreting http messages is not that common any more.

REST was a nice idea when it got (re)invented about ten years after Fielding's thesis but it left too much open for debate, ambiguity, and nitpicking and quickly degenerated in different opinionated camps trying to retrofit new ideas to the existing practices around http, which mainly boiled down to interesting ways to do RPC.

Before HTTP, people were already long doing RPC using e.g. DCOM, CORBA,RMI, etc. Reinveinting RPC over X has been the fate of pretty much every way we've come up with to make two computers talk to each other.

2 comments

> Before then, REST was not a really a thing.

You only need GET and POST for REST.

> Reinveinting RPC over X has been the fate of pretty much every way we've come up with to make two computers talk to each other.

REST isn't just RPC, it's RPC with specific constraints to enable caching, scaling, adaptability, and distribution properties that unrestricted RPC alone cannot achieve.

That's why REST is still important today, because RPC is too flexible, and RPC without constraints will inevitably run head first into all of the issues that REST solves for you. Unrestricted RPC libraries then let you "solve" these problems in myriad incompatible ways each with their own problems.

> Unrestricted RPC libraries then let you "solve" these problems in myriad incompatible ways each with their own problems.

I mean, this is exactly the state of REST today. It's not specified well enough to admit general purpose clients (like, for example, GraphQL does) because it's just a "pattern" not a specification.

Because every API has its own way of doing paging, subresource expansion, expressing side-effectful operations, etc it means every API has a corresponding custom-built client.

> Caching

Do these custom clients implement http caching? Not usually.

> Scaling

Arguably, REST is responsible for bringing about the rise of stateless API servers. We should be grateful for the good idea, and not feel compelled to adhere to the other aspects of REST if they don't suit our purposes.

> adaptability

Claims of additional adaptability in REST are usually talking about HATEOAS where each resource defines how it can be interacted with by providing links and semantic metadata etc. I will flat out say it: this doesn't work. Short of building some intelligent agent into your API client, hypertext will never be the engine of application state in any meaningful way. You can't just change the links and have the client magically discover the right thing. Fielding's thesis was talking about the web, where humans are the ones deciding which links to follow. It's a useless concept in API design, and it adds tremendous overhead for zero benefit.

You need a client that understands the media type it's retrieving, yes. That's the same for all clients, using HATEOAS or not.
> I mean, this is exactly the state of REST today. It's not specified well enough to admit general purpose clients (like, for example, GraphQL does) because it's just a "pattern" not a specification.

I don't think that's true. It's very well specified, it's just an extensible specification admitting many possible hypermedia formats. There is no one single hypermedia format to rule them all. Fielding's thesis was about the architecture that allowed the web to scale, and content negotiation and extensible content types are part of that.

> Because every API has its own way of doing paging, subresource expansion, expressing side-effectful operations, etc it means every API has a corresponding custom-built client.

This isn't necessary, depending on what you mean by "client". All such operations should be encapsulated as links embedded within a hypermedia format. The client needs only to know the high-level workflow or path to navigate the hypermedia and extract the links it needs.

The hypermedia format itself can change, the links can change, but as long as the path through the hypermedia is preserved, the client works. And there are ways to increase adaptability even further if you don't want to hardcode a path through a set of hypermedia documents, like a flat directory of endpoints (but it's similar to the path, since there must be some shared semantic knowledge about what you're looking for).

> Short of building some intelligent agent into your API client, hypertext will never be the engine of application state in any meaningful way. You can't just change the links and have the client magically discover the right thing.

It sounds like you misunderstand the use of hypermedia for autonomous agents. Throw out HTML and consider a hypermedia format that has only two node types: a named embedded link, and non-link data. An autonomous program can then enumerate all links, or access specific named links it's interested in that may be deeply or shallowly embedded within a web of hypermedia documents.

Most endpoints will probably be shallowly embedded, like with PWAs where the JS simply does a form of RPC with the server. But if you consider more complicated aggregated services, like interacting with someone's bank account where the number of services is large and managed by separate teams (mortgage, stock broker, chequeing, etc.), then it starts to make sense to require deeper embeddings to permit better organization of your teams developing distinct programs on the server-side.

The point being that REST gives you considerably more server-side flexibility to do this.

> It sounds like you misunderstand the use of hypermedia for autonomous agents.

Every time you type hypermedia I want to punch you.

Exposure therapy is supposedly effective for anger problems, so let me help you out:

hypermedia, hypermedia, hypermedia, hypermedia, hypermedia, hypermedia, hypermedia, hypermedia, hypermedia, hypermedia, hypermedia, hypermedia, hypermedia, hypermedia, hypermedia, hypermedia, hypermedia, hypermedia, hypermedia, hypermedia, hypermedia, hypermedia, hypermedia, hypermedia, hypermedia, hypermedia, hypermedia, hypermedia, hypermedia, hypermedia, hypermedia, hypermedia, hypermedia, hypermedia, hypermedia, hypermedia, hypermedia, hypermedia, hypermedia, hypermedia!!

> Before HTTP, people were already long doing RPC using e.g. DCOM, CORBA,RMI, etc. Reinveinting RPC over X has been the fate of pretty much every way we've come up with to make two computers talk to each other.

The key difference between Representational State Transfer and RPC, which makes all of the other capabilities of REST possible, is:

REST deals with nouns and uses HTTP verbs (the common ones, or you can invent your own) to handle a specific and common grammar of operations against those verbs:

  POST   _hyn3 > /user # (C)reate
  GET    /user/_hyn3    # (R)ead
  PUT    /user/_hyn3    # (U)pdate
  GET    /users < _hyn3 #     List
  DELETE /user/_hyn3 # (D)elete

RPC was literally "remote procedure call", which means you're calling a remote verb and then specifying your noun as an argument or data:

  POST   _hyn3 > /users/create_user
  GET    /users/get_user/_hyn3
  POST   /users/update_user/_hyn3
  GET    /users/list_users < _hyn3
  POST   /users/delete_user/_hyn3
It's more than just semantics, because it gave a common language for almost all CRUD type operations. (Thus, even though REST was never about CRUD, as the titular article states, CRUD and REST do have a lot in common, because CRUD represents an extremely common data access pattern and common HTTP verbs, if not REST itself, map to it very cleanly and nicely.)

In other words: REST deals with HTTP and the facilities that it provides. It doesn't directly with the verbs behind HTTP, such as GET/PUT/DELETE/etc. It instead provides an architectural paradigm shift, in which the URL itself is a discrete representation of the data in question, and the verbs -- RPC's -- are just standardized ways of dealing with that data.

This seemingly simple change, obvious only in hindsight, set the stage for a massive change in how API's are produced and consumed.