Hacker News new | past | comments | ask | show | jobs | submit login

> > A signature characteristic of [REST APIs] is that clients do not construct URLs from other information

> I don't think this is true in practice.

'recursivedoubts: https://news.ycombinator.com/item?id=42799917

The blogger is completely correct. In a true REST (i.e., not JSON-RPC) API, the client has a single entry URL, then calls the appropriate HTTP verb on it, then parses the response, and proceeds to follow URLs; it does not produce its own URLs. Hypertext as the engine of application state.

For example, there might be a URL http://foocorp.example/. My OrderMaker client might GET http://foo.example/, Accepting type application/offerings. It gets back a 200 response of type application/offerings listing all the widgets FooCorp offers. The offerings document might include a URL with an order-creation relationship. That URL could be http://foocorp.example/orders, or it could be http://foocorp.example/82347327462, or it could be https://barcorp.example/cats/dog-attack/boston-dysentery — it seriously doesn’t matter.

My client could POST to that URL and then get back a 401 Unauthorized response with a WWW-Authenticate header with the value ‘SuperAuthMechanism system="baz"’, and then my client could prompt me for the right credentials and retry the POST with an Authorization header with the value ‘SuperAuthMechanism opensesame’ and receive a 201 response with a Location header containing a URL for the new empty order. That could be http://foocorp.example/orders/1234, or it could be https://grabthar.example/hammer — what matters is that my client knows how to interact with it using HTTP verbs, headers and content types, not what the URL’s characters.

Then my client might POST a resource with content type application/order-item describing a widget to that order URL, and get back 202 Accepted. Then it might POST another resource describing a gadget, and get back 202 Accepted. Then it might GET the original order URL, and get back a 200 OK of type application/order which shows the order in an unconfirmed state. That resource might include a particular confirm URL to PUT to, or perhaps my client might POST a resource with content type application/order-confirmation — all that would be up to the order protocol definition (along with particulars like 202, or 200, or 201, or whatever).

Eventually my client non-idempotently PUTs or POSTs or whatever, and from then on can poll the order URL and see it change as FooCorp fulfills it.

That’s a RESTful API. The World Wide Web itself is a RESTful API for dealing with documents and also complete multimedia applications lying about being documents, but the RESTful model can be applied to other things. You can even build a RESTful application using the same backend code in the example, but which talks HTML to human beings whose browsers ask for text/html instead of application/whatever. Or you might build a client which asks for ‘text/html; custom=orderML’ and knows how to parse the expected HTML to extract the right information, and everything shares common backend code.

Or you might use htmx and make all this reasonably easy and straightforward.

That’s what REST is. What REST is not, is GETting http://api.foocorp.example/v1/order/$ORDERID and getting back a JSON blob, then parsing out an item ID from the JSON blob, then GETting http://api.foocorp.example/v1/item/$ITEMID and so forth.




I think there's the REST that Fielding intended, and there's the REST that everyone has spent almost 20 years implementing. At some point we should acknowledge that the reality of REST-like API design is a valid thing to point to and say "that's REST!" even if it doesn't implement all of Fielding's intentions.

To me the critical part of REST is the use of http semantics in API design, which makes it very un-RPC like.

The idea of a naive api client crawling through an API to get at the data that it needs seems so disconnected from the reality of how _every api client I've ever implemented_ works in a practical sense that it's unfathomable to me that someone thinks that this is a good idea. I mean, as a client, I _know_ that I want to fetch a specific `order` object, and I read the documentation from the API provider (which may in fact be me as well, at least me as an organization). I know the URL to load an order is GET /orders/:id, and I know the url to logout is DELETE /loginSession. It would never make sense to me to crawl an API that I understand from the docs to figure out if somehow the url for fetching orders has changed.

I do think we need some kind of description of REST 2.0 that makes sense in today's world. It certainly does not involve clients crawling through entry urls and relationships to discover paths that are clearly documented. It probably does involve concepts of resources and collections of resources, it certainly mandates specific uses for each http method. It should be based on the de facto uses of REST in the wild. And this thing would _definitely_ not look like an rpc-oriented api (eg soap, grpc).


Thank you for the summary! :)




Consider applying for YC's Spring batch! Applications are open till Feb 11.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: