HATEOAS: Hypermedia as the Engine of Application State(htmx.org)
htmx.org
HATEOAS: Hypermedia as the Engine of Application State
https://htmx.org/essays/hateoas/
95 comments
> You need some substantial understanding of language and the world to figure out where this link will take you.
> <a href="/accounts/12345/close-requests">close-requests</a>
There's two types of understanding here: a technical understanding of hypermedia behaviours, and a contextual understanding of application domain intents. A hypermedia client doesn't need to understand the latter at all: it only needs the former to be able to present a user with direct context (whether the user can then understand what to do is mostly up to the application designers, but it's outside of the responsibility of the hypermedia client - it's just the messenger here).
For example: this is a HTML anchor element (presumably the client has been served a Content-Type: text/html header here to inform it of that) - HTML anchors initiate GET requests to an associated href. In this case the href starts with a / indicating that it is relative to the serving origin. That's the beginning and end of so the hypermedia client needs to know: all self contained, no out-of-band knowledge required.
Any further confusion suffered by the user related to financial or English language knowledge is up to domain knowledge of the application and not within the bounds of what HATEOAS does.
> <a href="/accounts/12345/close-requests">close-requests</a>
There's two types of understanding here: a technical understanding of hypermedia behaviours, and a contextual understanding of application domain intents. A hypermedia client doesn't need to understand the latter at all: it only needs the former to be able to present a user with direct context (whether the user can then understand what to do is mostly up to the application designers, but it's outside of the responsibility of the hypermedia client - it's just the messenger here).
For example: this is a HTML anchor element (presumably the client has been served a Content-Type: text/html header here to inform it of that) - HTML anchors initiate GET requests to an associated href. In this case the href starts with a / indicating that it is relative to the serving origin. That's the beginning and end of so the hypermedia client needs to know: all self contained, no out-of-band knowledge required.
Any further confusion suffered by the user related to financial or English language knowledge is up to domain knowledge of the application and not within the bounds of what HATEOAS does.
If you read the article, it's pretty clear that they're not advocating using HATEOAS for a computer-consumable API—it's all HTML, meant to be rendered by a web browser and clicked on by the user. You could code a computer agent against this as well, but a hypermedia system is designed for users first.
In that case your REST API is just a new name for web application and your API responses are just web pages.
Yes, exactly. The confusion (not unique on your part) comes from the notion that REST has something to do with the JSON/XML APIs that the term conjures up in your mind. Whoever said that's what it was supposed to mean? (Lots of people, I know. The point is, they're wrong.) REST is just how the Web works (or at least worked—at the time that Fielding wrote his dissertation).
jcrites explains it really well: <https://news.ycombinator.com/item?id=23672561>
The answer to your question, "has anyone ever made a non-toy implementation conforming to the idea of HATEOAS?", therefore, is "Yeah. Your Web browser."
Disabuse yourself of anything you have ever been told that has led you to believe REST is an alternative to (or a special flavor of) RPC. It's not about RPC.
jcrites explains it really well: <https://news.ycombinator.com/item?id=23672561>
The answer to your question, "has anyone ever made a non-toy implementation conforming to the idea of HATEOAS?", therefore, is "Yeah. Your Web browser."
Disabuse yourself of anything you have ever been told that has led you to believe REST is an alternative to (or a special flavor of) RPC. It's not about RPC.
Then I will have to read the thesis once more. Sigh. I am pretty sure it talks about APIs, that is interfaces consumable by software. What a browser does, formatting and rendering a response, is not what I would call consuming an API. Well, the browser is actually consuming an API, it sends URLs and receives HTML or whatever. Is that the API the thesis has in mind, HTTP itself, while I was always thinking about the one on top, the one that lets me transfer money from my account to someone else? In some ways that would make sense, in others not at all.
> "Is that the API the thesis has in mind, HTTP itself, while I was always thinking about the one on top, the one that lets me transfer money from my account to someone else?"
Yep, that's it.
Field's REST/HATEOAS can be used as a "layer" underneath a more traditional, schema-bound, RPC-like API. This is what Google did with GData, for example.
Yep, that's it.
Field's REST/HATEOAS can be used as a "layer" underneath a more traditional, schema-bound, RPC-like API. This is what Google did with GData, for example.
I don’t think that is a good explanation.
> REST is about describing services that you can interact with with no prior knowledge. REST is about completely decoupling the client and server (in terms of prior knowledge) beyond standardized media types (HTML, CSS, JS)
The idea that REST is confined to standard media types like HTML and CSS is wrong. It is sufficient that media types are known to specific clients and server, but that does not have to include web browsers or arbitrary clients.
Quote [1]:
REST provides a hybrid of all three options by focusing on a shared understanding of data types with metadata, but limiting the scope of what is revealed to a standardized interface. REST components communicate by transferring a representation of a resource in a format matching one of an evolving set of standard data types, selected dynamically based on the capabilities or desires of the recipient and the nature of the resource. Whether the representation is in the same format as the raw source, or is derived from the source, remains hidden behind the interface. The benefits of the mobile object style are approximated by sending a representation that consists of instructions in the standard data format of an encapsulated rendering engine (e.g., Java [45]).
[1] https://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arc...
> REST is about describing services that you can interact with with no prior knowledge. REST is about completely decoupling the client and server (in terms of prior knowledge) beyond standardized media types (HTML, CSS, JS)
The idea that REST is confined to standard media types like HTML and CSS is wrong. It is sufficient that media types are known to specific clients and server, but that does not have to include web browsers or arbitrary clients.
Quote [1]:
REST provides a hybrid of all three options by focusing on a shared understanding of data types with metadata, but limiting the scope of what is revealed to a standardized interface. REST components communicate by transferring a representation of a resource in a format matching one of an evolving set of standard data types, selected dynamically based on the capabilities or desires of the recipient and the nature of the resource. Whether the representation is in the same format as the raw source, or is derived from the source, remains hidden behind the interface. The benefits of the mobile object style are approximated by sending a representation that consists of instructions in the standard data format of an encapsulated rendering engine (e.g., Java [45]).
[1] https://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arc...
I don't get what your quibble is.
> The idea that REST is confined to standard media types[...] is wrong
You sourced the response yourself:
> REST components communicate by transferring a representation of a resource in a format matching one of an evolving set of standard data types
... and given that you did just copy and paste that part, it leads me to believe that that's not what you've got an issue with. So what do you have an issue with?
> The idea that REST is confined to standard media types[...] is wrong
You sourced the response yourself:
> REST components communicate by transferring a representation of a resource in a format matching one of an evolving set of standard data types
... and given that you did just copy and paste that part, it leads me to believe that that's not what you've got an issue with. So what do you have an issue with?
„Standard media type” has different meaning in the comment you refer to and in the quote.
This is not a very helpful response.
You reference a comment that basically says that REST is HTML UI talking to server via links and forms, rather than interaction with JSON or XML-based API. This is not correct, neither according to original dissertation nor according to modern understanding of RMM 3 APIs. API using JSON can support HATEOAS. Standard media type in the sense of REST is not the W3C media type, but anything that both server and client can understand. appilcation/hal+json is a good example.
Nope. Try again. It "basically" says what it says—which is the same thing that the part you quoted from Fielding says—and nowhere does it say that the media type has to be HTML, which is what you (now) seem to be implying (but are unable or unwilling to articulate for some reason).
How exactly do you understand the following quote that is part of what you call a „good explanation“?
> REST is about completely decoupling the client and server (in terms of prior knowledge) beyond standardized media types (HTML, CSS, JS)
> REST is about completely decoupling the client and server (in terms of prior knowledge) beyond standardized media types (HTML, CSS, JS)
I understand it the way it's written. I don't know what you're looking for here; jcrites is not staying that { HTML, CSS, JS } are prerequisites to REST. They're giving examples of standard media types. If there are other media types for which it is possible to do REST, then those are acceptable, too, of course. But HTML is not a requirement.
The comment you're complaining about says "beyond standardized media types (HTML, CSS, JS)".
"Beyond" in this case means "not only".
"Beyond" in this case means "not only".
You're absolutely correct in stating REST is not confined to HTML, CSS, JS. A JSON, XML, or binary-based media type are all compatible with the architectural style.
I don't think the grandparent implies otherwise, though. They are using the browser/HTML example to describe the particular mechanics of client/server interaction, which are key to a REST application.
They also bring up "decoupling the client and server (in terms of prior knowledge)". As far as I understand, this isn't about an ability of an arbitrary client to talk to the server.
This is, again, easier to explain using the web browser as an example, but the principle equally applies to any client. Think of a "traditional" web application (Django, RoR, etc).
Say, one day you decide to completely rewrite it -- add new pages, remove some existing pages, change the site structure (as in which pages the user can navigate to from a given page). While the app has changed beyond recognition, the user doesn't need to download a new version of browser, they can still point their existing browser to the app's home page and it will just work.
Now, all of the above should hold for a RESTful app based on a binary media type. I believe, this is the key point of going REST-way.
There's a trade-off, of course. While the client is decoupled from the server along one axis, they are fundamentally coupled along another. Imagine a RESTful banking app, and let's say we would like to add a list of recent transactions to the home screen of a mobile client, but the server resource representing the home screen doesn't encode this list in any way. Well, there's is no way to just add it on the client in this case, at least without breaking the principles of REST hence defying the whole purpose of choosing this architectural style in the first place. We have to change the backend code in this case.
I can readily see how the limitation described above might be a deal-breaker for a lot of apps as we know them today.
I don't think the grandparent implies otherwise, though. They are using the browser/HTML example to describe the particular mechanics of client/server interaction, which are key to a REST application.
They also bring up "decoupling the client and server (in terms of prior knowledge)". As far as I understand, this isn't about an ability of an arbitrary client to talk to the server.
This is, again, easier to explain using the web browser as an example, but the principle equally applies to any client. Think of a "traditional" web application (Django, RoR, etc).
Say, one day you decide to completely rewrite it -- add new pages, remove some existing pages, change the site structure (as in which pages the user can navigate to from a given page). While the app has changed beyond recognition, the user doesn't need to download a new version of browser, they can still point their existing browser to the app's home page and it will just work.
Now, all of the above should hold for a RESTful app based on a binary media type. I believe, this is the key point of going REST-way.
There's a trade-off, of course. While the client is decoupled from the server along one axis, they are fundamentally coupled along another. Imagine a RESTful banking app, and let's say we would like to add a list of recent transactions to the home screen of a mobile client, but the server resource representing the home screen doesn't encode this list in any way. Well, there's is no way to just add it on the client in this case, at least without breaking the principles of REST hence defying the whole purpose of choosing this architectural style in the first place. We have to change the backend code in this case.
I can readily see how the limitation described above might be a deal-breaker for a lot of apps as we know them today.
Yes, that's essentially their point—REST started as a description of a good hypertext architecture and was coopted to describe just about any JSON API. HATEOAS only makes sense in the original context.
> In the early 2000s the concept of REST was appropriated from its initial conceptual environment as a description of the early web into other areas of web development
> In the early 2000s the concept of REST was appropriated from its initial conceptual environment as a description of the early web into other areas of web development
> Yes, that's essentially their point—REST started as a description of a good hypertext architecture and was coopted to describe just about any JSON API. HATEOAS only makes sense in the original context.
I don't think that your opinion is valid. What you refer as "JSON API" is actually just resources being represented with a specific JSON-based media type, in the same way that opening a page is actually a resource represented as a HTML-based media type. Some web scrapers are basically HATEOAS clients.
I don't think that your opinion is valid. What you refer as "JSON API" is actually just resources being represented with a specific JSON-based media type, in the same way that opening a page is actually a resource represented as a HTML-based media type. Some web scrapers are basically HATEOAS clients.
I believe the grandparent is making a valid point. It depends on implicit assumptions we have in mind reading it.
The way I'm reading your comment, that JSON-based (or XML-based, or some binary format-based for that matter) media type encodes hyperlinks in some form. Then the client is a simplified, specialized browser, if you will. But the mechanics of client/server interaction are essentially the same as a "traditional" web application (as in Django, RoR, PHP, etc).
And if it's a machine-to-machine interaction, the client is very simalar to a web crawler/scraper, although the media types it parses is not necessary HTML.
In other words, you are absolutely right in that REST is non confined to HTML.
What the grandparent means by JSON API, I think, is the kind of HTTP API we are used to see designed for mobile and SPA clients -- pretty URIs for endpoints, HTTP methods, JSON-serialized request/response bodies...
Those can actually be very nice API, pleasant to work with. It's just that it's not REST.
But at this point, it's probably more productive to go with the flow and just accept people refer to such API as REST.
That said, to me, understanding the difference is still valuable. Even if I'm not going to mention it out loud in a work setting.
The way I'm reading your comment, that JSON-based (or XML-based, or some binary format-based for that matter) media type encodes hyperlinks in some form. Then the client is a simplified, specialized browser, if you will. But the mechanics of client/server interaction are essentially the same as a "traditional" web application (as in Django, RoR, PHP, etc).
And if it's a machine-to-machine interaction, the client is very simalar to a web crawler/scraper, although the media types it parses is not necessary HTML.
In other words, you are absolutely right in that REST is non confined to HTML.
What the grandparent means by JSON API, I think, is the kind of HTTP API we are used to see designed for mobile and SPA clients -- pretty URIs for endpoints, HTTP methods, JSON-serialized request/response bodies...
Those can actually be very nice API, pleasant to work with. It's just that it's not REST.
But at this point, it's probably more productive to go with the flow and just accept people refer to such API as REST.
That said, to me, understanding the difference is still valuable. Even if I'm not going to mention it out loud in a work setting.
In that case what's the point of any of it? The user doesn't care about how your URLs are structured. They just read pages and click links, and anything below that is up to the programmer's preference
> The user doesn't care about how your URLs are structured.
This sounds like you're still thinking that REST is supposed to mean what you thought it meant before (and that it somehow has something to do with "how your URLs are structured").
This sounds like you're still thinking that REST is supposed to mean what you thought it meant before (and that it somehow has something to do with "how your URLs are structured").
I'm struggling to glean any meaning out of multiple explanations of HATEOAS beyond "response bodies with hyperlinks in them". Whatever it is, it's too unstructured for computers to automatically use, and unnecessary for humans, who are quite capable of using, well, any website designed for a human
The phrase "hypermedia as the engine of application state" is something Fielding came up with when philosophizing about the architectural style of the Web circa 2000 and how it differed from other architectural styles. That's all it is. That it's "too unstructured for computers to automatically use" is not a failure case, because there was no objective other than to describe how the Web worked. He was developing a taxonomy—to guide how things should (continue to) work based on the world as it already is—not trying to invent something new and admonish people that "Hey, this is how we really ought to be doing things"—unlike the tone of many articles that you've probably read about the promises of this whole "REST" thing, right?
If you expect it to be anything else at this point, then you are sure to end up disappointed, because you are setting yourself up for failure by thinking that it's something that it's not. Kinda sucks that an entire industry misled you into thinking otherwise, but that is its wont...
If you expect it to be anything else at this point, then you are sure to end up disappointed, because you are setting yourself up for failure by thinking that it's something that it's not. Kinda sucks that an entire industry misled you into thinking otherwise, but that is its wont...
Think of a "traditional" web application (Django, RoR, etc).
Say, one day you decide to completely rewrite it -- add new pages, remove some existing pages, change the site structure (as in which pages the user can navigate to from a given page). While the app has changed beyond recognition, the user doesn't need to download a new version of browser, they can still point their existing browser to the app's home page and it will just work. This is an app based on the REST architectural style.
Now, if instead of such a web application we have one based on a binary media type instead of HTML and a custom client instead of the browser, but otherwise everything described above still apply, this is a RESTful app too.
If a decoupling like this is a priority for an app, REST is a good choice for it.
There's a trade-off, of course. While the client is decoupled from the server along one axis, they are fundamentally coupled along another. Imagine a RESTful banking app, and let's say we would like to add a list of recent transactions to the home screen of a mobile client, but the server resource representing the home screen doesn't encode this list in any way. Well, there's is no way to just add it on the client in this case, at least without breaking the principles of REST hence defying the whole purpose of choosing this architectural style in the first place.
We have to change the backend code any time we want to change what's available on one of client screen's and where the user can navigate from that screen. This can be a deal-breaker limitation for a lot of apps. They're better off designed around another architectural style -- an API having pretty URIs for endpoints, JSON-serialized request/response bodies, utilizing HTTP method for CRUD operations is one such alternative.
> Whatever it is, it's too unstructured for computers to automatically use, and unnecessary for humans, who are quite capable of using, well, any website designed for a human
Another person posted a good answer to this part of your comment. But let me respond to it too.
"any website designed for a human" is an instance of REST/HATEOAS architecture by definition. Roy Fielding came up with the name to describe software systems organized exactly like this.
> it's too unstructured for computers to automatically use
Indeed. In my opinion, designing an app meant for automatic consumption by a computer in RESTful style is not a great idea.
Say, one day you decide to completely rewrite it -- add new pages, remove some existing pages, change the site structure (as in which pages the user can navigate to from a given page). While the app has changed beyond recognition, the user doesn't need to download a new version of browser, they can still point their existing browser to the app's home page and it will just work. This is an app based on the REST architectural style.
Now, if instead of such a web application we have one based on a binary media type instead of HTML and a custom client instead of the browser, but otherwise everything described above still apply, this is a RESTful app too.
If a decoupling like this is a priority for an app, REST is a good choice for it.
There's a trade-off, of course. While the client is decoupled from the server along one axis, they are fundamentally coupled along another. Imagine a RESTful banking app, and let's say we would like to add a list of recent transactions to the home screen of a mobile client, but the server resource representing the home screen doesn't encode this list in any way. Well, there's is no way to just add it on the client in this case, at least without breaking the principles of REST hence defying the whole purpose of choosing this architectural style in the first place.
We have to change the backend code any time we want to change what's available on one of client screen's and where the user can navigate from that screen. This can be a deal-breaker limitation for a lot of apps. They're better off designed around another architectural style -- an API having pretty URIs for endpoints, JSON-serialized request/response bodies, utilizing HTTP method for CRUD operations is one such alternative.
> Whatever it is, it's too unstructured for computers to automatically use, and unnecessary for humans, who are quite capable of using, well, any website designed for a human
Another person posted a good answer to this part of your comment. But let me respond to it too.
"any website designed for a human" is an instance of REST/HATEOAS architecture by definition. Roy Fielding came up with the name to describe software systems organized exactly like this.
> it's too unstructured for computers to automatically use
Indeed. In my opinion, designing an app meant for automatic consumption by a computer in RESTful style is not a great idea.
[Ed: correct] Caching.
Humans can just as easily read an OpenApi spec.
"Seriously, has anyone ever made a non-toy implementation conforming to the idea of HATEOAS?"
Yep, your web browser uses hypermedia. But if you want something that is an API, then there is OData, GData and AtomPub all follow HATEOAS.
Yep, your web browser uses hypermedia. But if you want something that is an API, then there is OData, GData and AtomPub all follow HATEOAS.
My browser has no idea how to interact with a proper HATEOAS conforming REST API, I would be doing that, the browser would just show me responses. And if one claims that this is all that is necessary, because the API response already contains some HTML form for me to interact with, then you have done nothing but relabeled web applications as REST APIs and API responses are just a web pages.
How do you consume an OData API without baking the structure of it into your code in one way or another? And just rendering generic list and detail views does not count, I think, that will most likely not provide any good user experience.
How do you consume an OData API without baking the structure of it into your code in one way or another? And just rendering generic list and detail views does not count, I think, that will most likely not provide any good user experience.
> "My browser has no idea how to interact with a proper HATEOAS conforming REST API"
Here's the thing: HTML via HTTP _is_ "proper HATEOAS conforming REST API", as far as was described by Roy Fielding. It follows the principles of REST, as it was the basis for the whole thing including REST.
> "How do you consume an OData API without baking the structure of it into your code in one way or another"
You need to know about OData to consume OData. HATEOAS is not about magic, it is about consuming formats that conform to a specification, such as HTML, OData, GData, AtomPub.
The resources are flexible and arbitrary, or can be generated at runtime. The format is not. It is previously agreed by client and server.
> "And just rendering generic list and detail views does not count, I think, that will most likely not provide any good user experience"
Well, HTML can do it. Some websites I use definitely have good user experience.
OData was very useful for me to expose databases to Excel users, and the user experience was alright according to these users.
If you're looking for something else, maybe there's some example out there. Is Gemini, or perhaps Gopher, compatible with HATEOAS? Maybe, I don't know. But if you're looking for "magic APIs", there's none. No magic was ever promised. Nor was "good user experience". REST is just an architectural pattern based on how HTML/HTTP work on the browser.
If you really want, perhaps you can always extend OData into another format to determine how forms, lists, confirmation dialogs, etc, will be rendered by a client. Heck, you could even send styling information. At this point you'll probably be reinventing part of HTML, though.
Here's the thing: HTML via HTTP _is_ "proper HATEOAS conforming REST API", as far as was described by Roy Fielding. It follows the principles of REST, as it was the basis for the whole thing including REST.
> "How do you consume an OData API without baking the structure of it into your code in one way or another"
You need to know about OData to consume OData. HATEOAS is not about magic, it is about consuming formats that conform to a specification, such as HTML, OData, GData, AtomPub.
The resources are flexible and arbitrary, or can be generated at runtime. The format is not. It is previously agreed by client and server.
> "And just rendering generic list and detail views does not count, I think, that will most likely not provide any good user experience"
Well, HTML can do it. Some websites I use definitely have good user experience.
OData was very useful for me to expose databases to Excel users, and the user experience was alright according to these users.
If you're looking for something else, maybe there's some example out there. Is Gemini, or perhaps Gopher, compatible with HATEOAS? Maybe, I don't know. But if you're looking for "magic APIs", there's none. No magic was ever promised. Nor was "good user experience". REST is just an architectural pattern based on how HTML/HTTP work on the browser.
If you really want, perhaps you can always extend OData into another format to determine how forms, lists, confirmation dialogs, etc, will be rendered by a client. Heck, you could even send styling information. At this point you'll probably be reinventing part of HTML, though.
Let's take a weather database. I point my browser to some URL, you send back some HTML that the browser shows to me. In order to get a nice, uniform architecture you have followed all the REST principles and I can click around in the database. Fine, you build a nice web application following REST principles.
What you did not do is build an REST API. API means consumable by software and just formatting and rendering the response does not count as consumption by software, at least in my book. I want to get the data and compute some statistics on it. For that I need to know the structure of the data in advance, need to know which URLs to retrieve, which operations to perform, which data structures to expect. That is what WSDL, OpenAPI and friends are for. That I can understand XML, JSON or OData is not good enough.
But if you do not make the structure of the API explicit somewhere and only tell me what I get and where I can go next while I am interacting with the API, what can I do except baking the structure into my code in one way or another? HATEOAS and API just do not work together. So what am I still not getting?
What you did not do is build an REST API. API means consumable by software and just formatting and rendering the response does not count as consumption by software, at least in my book. I want to get the data and compute some statistics on it. For that I need to know the structure of the data in advance, need to know which URLs to retrieve, which operations to perform, which data structures to expect. That is what WSDL, OpenAPI and friends are for. That I can understand XML, JSON or OData is not good enough.
But if you do not make the structure of the API explicit somewhere and only tell me what I get and where I can go next while I am interacting with the API, what can I do except baking the structure into my code in one way or another? HATEOAS and API just do not work together. So what am I still not getting?
> "What you did not do is build an REST API"
The API here is HTML + HTTP. That's it. A website is, as far as the API is concerned, just the content.
> "I want to get the data and compute some statistics on it. For that I need to know the structure of the data in advance, need to know which URLs to retrieve, which operations to perform, which data structures to expect"
Not needing to know the structure to automate usage of the content is not something that was exactly "promised" by REST. REST/HATEOAS is only about having standardized formats to display the hypermedia, make it discoverable within constraints (a browser for HTTP/HTML, a database program for OData, etc).
Even with websites, I might need previous knowledge to know where to navigate to, which URLs to access. When I come to Hacker News, I always click on "threads" at the top to see if anyone replied me. This is often discovered thanks to hypermedia (in this case a link). But in my case someone had to point it out to me (this is analogous to documentation).
> "So what am I still not getting?"
My assumption, but since you asked: I think you're expecting the original REST paper and hypermedia to be something that it isn't, and to apply to things it isn't supposed to. You're trying to apply it to arbitrary APIs that are supposed to be consumed exclusively by custom software. This doesn't really match its model or intent.
HTTP/HTML content is consumed by browsers. OData content is consumed by Excel, Access etc. AtomPub content is consumed by publishing/blogging/etc software. GData is a fun one: it is (was?) used as a foundation of traditional API clients.
Another assumption, but perhaps you're expecting hypermedia to replace something else? You're mentioning "WSDL, OpenAPI and friends". Well, those are perfectly fine, and they're orthogonal to REST and hypermedia. GData is a good example: Google APIs used GData as a foundation, but actually needed extra documentation and extra code on top to drive users to the correct endpoints.
The "discoverable" advantage of hypermedia APIs does not mean that applications should be intelligent and discover how to use the API just by accessing it. This is possible, don't get me wrong, but there will be massive constraints: either you build HTML/CSS/JS to allow arbitrary apps, or you have a simple tables app that consumes ODAta. If you want a fancy iPhone app, you'll have to start hardcoding a lot of assumptions into the app.
The H of HATEOAS means hypermedia, a term created by Ted Nelson in the 60s. It's related to hypertext, which is the HT of HTML and HTTP. HATEOAS/REST is about creating hypermedia APIs, including HTML/HTTP. This means rich context, like Wikipedia, a database, or a Website.
Not everything matches this. The app I work on doesn't. And that's completely fine.
The API here is HTML + HTTP. That's it. A website is, as far as the API is concerned, just the content.
> "I want to get the data and compute some statistics on it. For that I need to know the structure of the data in advance, need to know which URLs to retrieve, which operations to perform, which data structures to expect"
Not needing to know the structure to automate usage of the content is not something that was exactly "promised" by REST. REST/HATEOAS is only about having standardized formats to display the hypermedia, make it discoverable within constraints (a browser for HTTP/HTML, a database program for OData, etc).
Even with websites, I might need previous knowledge to know where to navigate to, which URLs to access. When I come to Hacker News, I always click on "threads" at the top to see if anyone replied me. This is often discovered thanks to hypermedia (in this case a link). But in my case someone had to point it out to me (this is analogous to documentation).
> "So what am I still not getting?"
My assumption, but since you asked: I think you're expecting the original REST paper and hypermedia to be something that it isn't, and to apply to things it isn't supposed to. You're trying to apply it to arbitrary APIs that are supposed to be consumed exclusively by custom software. This doesn't really match its model or intent.
HTTP/HTML content is consumed by browsers. OData content is consumed by Excel, Access etc. AtomPub content is consumed by publishing/blogging/etc software. GData is a fun one: it is (was?) used as a foundation of traditional API clients.
Another assumption, but perhaps you're expecting hypermedia to replace something else? You're mentioning "WSDL, OpenAPI and friends". Well, those are perfectly fine, and they're orthogonal to REST and hypermedia. GData is a good example: Google APIs used GData as a foundation, but actually needed extra documentation and extra code on top to drive users to the correct endpoints.
The "discoverable" advantage of hypermedia APIs does not mean that applications should be intelligent and discover how to use the API just by accessing it. This is possible, don't get me wrong, but there will be massive constraints: either you build HTML/CSS/JS to allow arbitrary apps, or you have a simple tables app that consumes ODAta. If you want a fancy iPhone app, you'll have to start hardcoding a lot of assumptions into the app.
The H of HATEOAS means hypermedia, a term created by Ted Nelson in the 60s. It's related to hypertext, which is the HT of HTML and HTTP. HATEOAS/REST is about creating hypermedia APIs, including HTML/HTTP. This means rich context, like Wikipedia, a database, or a Website.
Not everything matches this. The app I work on doesn't. And that's completely fine.
Excellent points.
As for:
> My assumption, but since you asked: I think you're expecting the original REST paper and hypermedia to be something that it isn't, and to apply to things it isn't supposed to. You're trying to apply it to arbitrary APIs that are supposed to be consumed exclusively by custom software.
I just want to point out that Fielding in his thesis details many different types of architectures. His focus is on REST and hypermedia - and especially how it fits well with efficient and correct caching.
But he talks about movable code (java applets, or essentially also modern JavaScript applications like those built around React), RPC etc.
I think the thesis remains relevant exactly because it's not only about REST.
As for:
> My assumption, but since you asked: I think you're expecting the original REST paper and hypermedia to be something that it isn't, and to apply to things it isn't supposed to. You're trying to apply it to arbitrary APIs that are supposed to be consumed exclusively by custom software.
I just want to point out that Fielding in his thesis details many different types of architectures. His focus is on REST and hypermedia - and especially how it fits well with efficient and correct caching.
But he talks about movable code (java applets, or essentially also modern JavaScript applications like those built around React), RPC etc.
I think the thesis remains relevant exactly because it's not only about REST.
Yep, I think that's a very important point. Not every API has to conform to Fielding's view of REST or to have hypermedia/HATEOAS.
Okay, I guess now the pieces are falling into place, the same conclusion just occurred to me in a different part of the thread, HTTP is the REST API and not an API build on top of HTTP. I will read some things again with that in mind, but currently my primary thought is how confusingly HATEOAS seems to be explained everywhere. If I see the bank account example where I can inspect account balances and make transfers, I of course assume we are talking about some banking API and it never occurred to me in all the years that we are actually talking about HTTP. After all, when I have to implement or consume an API, it will be the banking API, not HTTP. If I write or consume some SOAP service, there is an existing SOAP implementation on top of which I work but I rarely think of SOAP itself as an API, even though it of course is.
Yes.
The goal of the paper is to define clients that are 100% decoupled from the applications being served by some server. The browser is of course the best example of that. The only "shared knowledge" is in HTTP and in the format (HTML, OData, AtomPub). Excel consuming arbitrary OData is another example, Excel only knows HTTP and OData, and it's able to consume arbitrary data sources.
If you want to have, say, a more user-friendly iPhone banking app, that's probably not gonna be an hypermedia app, it's just a regular application that's specific to your bank. This is not decoupled! Which is 100% fine, especially for user friendliness. For this you can start hardcoding URLs and baking in some assumptions, customizing some screens in the app. All of that is fine, but it's beyond the scope of "pure" hypermedia. Which is fine.
The goal of the paper is to define clients that are 100% decoupled from the applications being served by some server. The browser is of course the best example of that. The only "shared knowledge" is in HTTP and in the format (HTML, OData, AtomPub). Excel consuming arbitrary OData is another example, Excel only knows HTTP and OData, and it's able to consume arbitrary data sources.
If you want to have, say, a more user-friendly iPhone banking app, that's probably not gonna be an hypermedia app, it's just a regular application that's specific to your bank. This is not decoupled! Which is 100% fine, especially for user friendliness. For this you can start hardcoding URLs and baking in some assumptions, customizing some screens in the app. All of that is fine, but it's beyond the scope of "pure" hypermedia. Which is fine.
> What you did not do is build an REST API. API means consumable by software and just formatting and rendering the response does not count as consumption by software, at least in my book. I want to get the data and compute some statistics on it. For that I need to know the structure of the data in advance, need to know which URLs to retrieve, which operations to perform, which data structures to expect. That is what WSDL, OpenAPI and friends are for. That I can understand XML, JSON or OData is not good enough.
I think you have some degree of confusion on what REST is in general, and HATEOAs in particular.
"Which URLs to retrieve" is provided by the hypermedia format you requested for a particular resource. There are many HATEOAS-based specifications for formats. Your client asks for the ones it supports when sending a request,and the server delivers one based on your request and what it supports.
"Which operations to perform" is also specified as part of the hypermedia format you requested. Your format specifies link relationships valid for a resource according to it's current state.
"Which data structure to expect" makes no sense and is a reflection of the degree of confusion you're in. Your client is responsible for specifying which media type it can consume. The "data structure to expect" is specified as part of the media type. If your client expects specific data structures, it needs to support specific media types that represents them. These media types are not application/json or application/xml. They are media types designed to reflect the format used to express your resource.
> what can I do except baking the structure into my code in one way or another?
You're missing the whole point. With REST, the "structure" that you "bake into your code" is not the URLs, operations, or data formats. You only need a single root resource as the entry point, and that resource expresses all link relations that you need to navigate towards your resource. The link relations provided by the resource already specify which other resources are available to your client, which also includes operations they currently support. Your client also has the responsibility of requesting the resources it wants expressed in the format it supports, which included the data format. I mean, if you write a Atom client you don't request application/xml. Instead, you request application/atom+xml.
If you need an analogy to understand the whole point, check how you navigate HackerNews with a browser. You open a resource representing the main page, and you're presented with a list of resources which include a collection of submissions, links to other collections reflecting specific queries such as new discussions, links to resources that allow you to login/logout or represent your user account. From that initial resource, you use the links provided in it to request other resources. If your current application state supports logging in, there will be a link to that. If your state is already logged in, there will be resources made available only in that state such as your account or logging out. If you opt to request a resource representing a submission, you'll get the submission text and/or link, along with comments. Each comment provides links to other resources such as individual comments, etc.
That's basically the whole point of REST. Do you hardcode references to each discussion or comment? No. you get them through links provided by other resources. Do you always get access to the resource representing your user account? No, that depends on the application state. Etc etc etc.
I think you have some degree of confusion on what REST is in general, and HATEOAs in particular.
"Which URLs to retrieve" is provided by the hypermedia format you requested for a particular resource. There are many HATEOAS-based specifications for formats. Your client asks for the ones it supports when sending a request,and the server delivers one based on your request and what it supports.
"Which operations to perform" is also specified as part of the hypermedia format you requested. Your format specifies link relationships valid for a resource according to it's current state.
"Which data structure to expect" makes no sense and is a reflection of the degree of confusion you're in. Your client is responsible for specifying which media type it can consume. The "data structure to expect" is specified as part of the media type. If your client expects specific data structures, it needs to support specific media types that represents them. These media types are not application/json or application/xml. They are media types designed to reflect the format used to express your resource.
> what can I do except baking the structure into my code in one way or another?
You're missing the whole point. With REST, the "structure" that you "bake into your code" is not the URLs, operations, or data formats. You only need a single root resource as the entry point, and that resource expresses all link relations that you need to navigate towards your resource. The link relations provided by the resource already specify which other resources are available to your client, which also includes operations they currently support. Your client also has the responsibility of requesting the resources it wants expressed in the format it supports, which included the data format. I mean, if you write a Atom client you don't request application/xml. Instead, you request application/atom+xml.
If you need an analogy to understand the whole point, check how you navigate HackerNews with a browser. You open a resource representing the main page, and you're presented with a list of resources which include a collection of submissions, links to other collections reflecting specific queries such as new discussions, links to resources that allow you to login/logout or represent your user account. From that initial resource, you use the links provided in it to request other resources. If your current application state supports logging in, there will be a link to that. If your state is already logged in, there will be resources made available only in that state such as your account or logging out. If you opt to request a resource representing a submission, you'll get the submission text and/or link, along with comments. Each comment provides links to other resources such as individual comments, etc.
That's basically the whole point of REST. Do you hardcode references to each discussion or comment? No. you get them through links provided by other resources. Do you always get access to the resource representing your user account? No, that depends on the application state. Etc etc etc.
I think their response would be something like: If you want that kind of data API then look at GraphQL which was designed to do that, not some misuse of REST which was designed to do the things they are talking about.
https://htmx.org/essays/hypermedia-apis-vs-data-apis/
edit to add key part:
> The crux point of this short essay is this: API churn is fine in a hypermedia system because the messages in a hypermedia system are self-describing. We can thrash the API around and the application doesn’t break: human users simply see the new hypermedia (HTML) and select what actions they want to do.
> Humans, compared with computers, are good at deciding what to do and are reasonably OK with change.
> This is in contrast with data APIs. Data APIs cannot be modified without breaking client code and thus must be much more disciplined in their changes. Data APIs also face pressure to provide higher levels of expressiveness so that they can satisfy more client needs without modification.
> This latter situation is especially dangerous when these data APIs are consumed in a browser, because any data-api expressiveness available to a front-end developer is also available to a potentially hostile user, who can fire up a console and begin hammering away at the API. Apparently, facebook uses a whitelist to deal with this.
> Do you?
https://htmx.org/essays/hypermedia-apis-vs-data-apis/
edit to add key part:
> The crux point of this short essay is this: API churn is fine in a hypermedia system because the messages in a hypermedia system are self-describing. We can thrash the API around and the application doesn’t break: human users simply see the new hypermedia (HTML) and select what actions they want to do.
> Humans, compared with computers, are good at deciding what to do and are reasonably OK with change.
> This is in contrast with data APIs. Data APIs cannot be modified without breaking client code and thus must be much more disciplined in their changes. Data APIs also face pressure to provide higher levels of expressiveness so that they can satisfy more client needs without modification.
> This latter situation is especially dangerous when these data APIs are consumed in a browser, because any data-api expressiveness available to a front-end developer is also available to a potentially hostile user, who can fire up a console and begin hammering away at the API. Apparently, facebook uses a whitelist to deal with this.
> Do you?
> Seriously, has anyone ever made a non-toy implementation conforming to the idea of HATEOAS?
Yes, the Web.
> Nothing but a generic understanding of hypermedia?
To understand basic structure and how to determine if you have the ability to do more; actually deep interaction requires knowledge of specific media types as well.
> But how on earth are you going to write software that can consume such an API, dynamically discover, understand and use available operations?
The basic software handles generic hypermedia, and there are modules to handle particular media types and interact with them. The meat solving a problem with REST is defining resource representations (on the service side), and then building handlers that do what you need with those resource types (on the client side).
Yes, the Web.
> Nothing but a generic understanding of hypermedia?
To understand basic structure and how to determine if you have the ability to do more; actually deep interaction requires knowledge of specific media types as well.
> But how on earth are you going to write software that can consume such an API, dynamically discover, understand and use available operations?
The basic software handles generic hypermedia, and there are modules to handle particular media types and interact with them. The meat solving a problem with REST is defining resource representations (on the service side), and then building handlers that do what you need with those resource types (on the client side).
I have been developing HATEOAS clients and servers for a while. The key to understanding of HATEOAS is that it is not about browsers or arbitrary clients, it is about abstraction. Client and server share the knowledge of the protocol, the data formats, logical names of links and semantics of operations with those links. Client does not need to maintain the complete state and complex business logic for that state, because it can derive the complete state and possible transitions from each server response. If some link is present in response, operation is possible, otherwise it is not. If link with given name exists and semantics imply GET, PATCH or POST, then make this request to this link. No constraint checks, no access management on client, just follow what server tells you. If server allows to cache resource, do it, but don’t forget to do HEAD.
Apache Causeway [1] generates a RESTful API that is HATEOAS compliant, and exists in parallel to the built-in viewer that is based on Wicket.
There are a few HATEOAS client projects out there, such as [2], that will generate a UI from such a (Restful) API. As far as I know it works quite well, but of course it's a bit rough on the edges.
One interesting observation is that the Wicket UI generated by Causeway does not itself use the RESTful API, but it uses the same meta model that is also used to generate the API.
[1] https://github.com/apache/causeway [2] https://github.com/lagoshny/ngx-hateoas-client
There are a few HATEOAS client projects out there, such as [2], that will generate a UI from such a (Restful) API. As far as I know it works quite well, but of course it's a bit rough on the edges.
One interesting observation is that the Wicket UI generated by Causeway does not itself use the RESTful API, but it uses the same meta model that is also used to generate the API.
[1] https://github.com/apache/causeway [2] https://github.com/lagoshny/ngx-hateoas-client
We are using ShareASpace for some things at work and they claim to use HATEOAS. Not sure where to link to prove it though…
https://docs.shareaspace.com/v1-8/developer/external-extensi...
I believe that Apple's AppStore Connect API uses HATEOAS. That's pretty non-trivial.
ramesh31(1)
I mean, you kinda answered the question there yourself. The whole REST paradigm (spearheaded by the Ruby on Rails community) was strongly influenced and modeled after the HATEOAS paper and ideas. There's some talks and papers about it but I'd have to dig them up, but basically the working reference implementation that shaped the web for years is here: https://guides.rubyonrails.org/routing.html
I am the author of this article.
I see a lot of people saying "HATEOAS doesn't work/has anyone ever used it".
The answer is YES: the world wide web and any traditional web 1.0 application uses it quite successfully. The important thing to realize is that an HTML-based web server is providing an API: a hypermedia-based API. It is providing it to a hypermedia client, namely the browser.
The concept has not mapped well to JSON-based data APIs because those APIs are not typically consumed by REST-ful clients. Or, if they are as in an SPA, the hypermedia functionality of the client is ignored in favor of a thick-client approach.
We have written a book on the idea of a hypermedia system that explains this in far more detail:
https://hypermedia.systems
which stresses the systemic nature of hypermedia when building a distributed application.
I see a lot of people saying "HATEOAS doesn't work/has anyone ever used it".
The answer is YES: the world wide web and any traditional web 1.0 application uses it quite successfully. The important thing to realize is that an HTML-based web server is providing an API: a hypermedia-based API. It is providing it to a hypermedia client, namely the browser.
The concept has not mapped well to JSON-based data APIs because those APIs are not typically consumed by REST-ful clients. Or, if they are as in an SPA, the hypermedia functionality of the client is ignored in favor of a thick-client approach.
We have written a book on the idea of a hypermedia system that explains this in far more detail:
https://hypermedia.systems
which stresses the systemic nature of hypermedia when building a distributed application.
Worth reading this: https://twobithistory.org/2020/06/28/rest.html
> REST purists often complain, for example, that so-called REST APIs aren’t actually REST APIs because they do not use Hypermedia as The Engine of Application State (HATEOAS). Fielding himself has made this criticism. According to him, a real REST API is supposed to allow you to navigate all its endpoints from a base endpoint by following links. If you think that people are actually out there trying to build REST APIs, then this is a glaring omission—HATEOAS really is fundamental to Fielding’s original conception of REST, especially considering that the “state transfer” in “Representational State Transfer” refers to navigating a state machine using hyperlinks between resources (and not, as many people seem to believe, to transferring resource state over the wire).8 But if you imagine that everyone is just building FIOH [author's acronym for "Fuck It, Overload HTTP"] APIs and advertising them, with a nudge and a wink, as REST APIs, or slightly more honestly as “RESTful” APIs, then of course HATEOAS is unimportant.
> REST purists often complain, for example, that so-called REST APIs aren’t actually REST APIs because they do not use Hypermedia as The Engine of Application State (HATEOAS). Fielding himself has made this criticism. According to him, a real REST API is supposed to allow you to navigate all its endpoints from a base endpoint by following links. If you think that people are actually out there trying to build REST APIs, then this is a glaring omission—HATEOAS really is fundamental to Fielding’s original conception of REST, especially considering that the “state transfer” in “Representational State Transfer” refers to navigating a state machine using hyperlinks between resources (and not, as many people seem to believe, to transferring resource state over the wire).8 But if you imagine that everyone is just building FIOH [author's acronym for "Fuck It, Overload HTTP"] APIs and advertising them, with a nudge and a wink, as REST APIs, or slightly more honestly as “RESTful” APIs, then of course HATEOAS is unimportant.
I’m not sure a “real” REST API has ever been built.
you best be believing in REST APIs... you're using one.
>While attempts have been made to impose more elaborate hypermedia controls on JSON APIs, broadly the industry has rejected this approach in favor of simpler RPC-style APIs that forego HATEOAS and other elements of the REST-ful architecture.
Because HATEOAS is basically useless for machines, and industry runs on machines.
It's fine when you've got a human clicking things that they're looking at, but there's no reliable way to reinterpret it for a different use because it's so wildly context sensitive in ways that only humans understand. Meaning of things in HATEOAS may be / is intentionally allowed to be communicated by non-structured text that accompanies the actions, as literally every example in this page shows.
If you're doing anything but rendering it for humans to interpret, that flexibility makes it basically impossible. Or binds you to a single output structure, with no way to structurally verify if changes are relevant or not.
Because HATEOAS is basically useless for machines, and industry runs on machines.
It's fine when you've got a human clicking things that they're looking at, but there's no reliable way to reinterpret it for a different use because it's so wildly context sensitive in ways that only humans understand. Meaning of things in HATEOAS may be / is intentionally allowed to be communicated by non-structured text that accompanies the actions, as literally every example in this page shows.
If you're doing anything but rendering it for humans to interpret, that flexibility makes it basically impossible. Or binds you to a single output structure, with no way to structurally verify if changes are relevant or not.
I think it's also basically useless for user interfaces.
The purpose of HATEOAS seems to be to provide web crawling clients (human or otherwise) visibility of the arbitrary actions/links that a particular endpoint provides in a particular state - but the links are disconnected from their context and intended interaction with the page. HATEOAS doesn't seem to acknowledge that a UI needs to provide context for user actions, or that API integrations are designed up front with full knowledge of the API contract .
It seems to me the only thing HATEOAS is useful for is browsing black and white pages with a bunch of blue and purple links. Or maybe SEO
The purpose of HATEOAS seems to be to provide web crawling clients (human or otherwise) visibility of the arbitrary actions/links that a particular endpoint provides in a particular state - but the links are disconnected from their context and intended interaction with the page. HATEOAS doesn't seem to acknowledge that a UI needs to provide context for user actions, or that API integrations are designed up front with full knowledge of the API contract .
It seems to me the only thing HATEOAS is useful for is browsing black and white pages with a bunch of blue and purple links. Or maybe SEO
HATEOAS is perfect for SPAs with server-side persistence because it allows to reduce complexity of the frontend and to avoid implementing things like security checks twice.
One point is that you should develop versioning with HATEOAS, instead of putting an ugly /v1/ into the URL.
I've done the HATEOAS thing as much as possible. Links were rendered in json like the site claims not to do. There is json-ld, of course, but that was just too much, so I didn't bother.
Can also do a nice trick of rendering nicely formatted json objects in html with proper links if a browser is requesting html/text. For an extra bonus split the page and render the docs right next to it, too. If application/json is requested, return just json to be consumed by programmatic clients.
That said, while it was really nice to learn and navigate the API from the browser that way, none of the programmatic clients ever used the "auto-discovery" feature. They jumped right to the resource the needed and didn't bother with the links.
At this point REST is just whatever most popular companies designed and called "REST-ful" is what REST-ful became. As much as Roy wants to claim it's not "pure" enough, the ship has sailed so speak.
Can also do a nice trick of rendering nicely formatted json objects in html with proper links if a browser is requesting html/text. For an extra bonus split the page and render the docs right next to it, too. If application/json is requested, return just json to be consumed by programmatic clients.
That said, while it was really nice to learn and navigate the API from the browser that way, none of the programmatic clients ever used the "auto-discovery" feature. They jumped right to the resource the needed and didn't bother with the links.
At this point REST is just whatever most popular companies designed and called "REST-ful" is what REST-ful became. As much as Roy wants to claim it's not "pure" enough, the ship has sailed so speak.
I consider it a fad, that we all go through when we're mid level devs wanting to use every shiny new thing. It's perfectly fine to use rest almost like JSON over grpc, or however you want the only thing is having good documentation for
Articles talking about "REST" and "HATEOAS" really need to define "client". Do they mean a person? Do they mean a web browser? Do they mean an application performing actions autonomously?
> A REST client needs little to no prior knowledge about how to interact with an application or server beyond a generic understanding of hypermedia.
If in this instance, "REST client" means an application performing actions autonomously, I don't see how this statement could possibly be true. Someone writing a client will need to know how the server is going to return responses to requests. It needs to know what operations the server supports.
It really seems like REST and HATEOAS, using the strictest definitions, really just mean server-side HTML rendering, which is nothing new. I figured we swapped to client-side rendering (And therefore, servers sending XML or JSON, and the client handles putting it into the page) to reduce server-side loads and the cost of increased CPU usage client-side.
> A REST client needs little to no prior knowledge about how to interact with an application or server beyond a generic understanding of hypermedia.
If in this instance, "REST client" means an application performing actions autonomously, I don't see how this statement could possibly be true. Someone writing a client will need to know how the server is going to return responses to requests. It needs to know what operations the server supports.
It really seems like REST and HATEOAS, using the strictest definitions, really just mean server-side HTML rendering, which is nothing new. I figured we swapped to client-side rendering (And therefore, servers sending XML or JSON, and the client handles putting it into the page) to reduce server-side loads and the cost of increased CPU usage client-side.
> Articles talking about "REST" and "HATEOAS" really need to define "client". Do they mean a person? Do they mean a web browser? Do they mean an application performing actions autonomously?
My understanding is yes, those are all clients.
> If in this instance, "REST client" means an application performing actions autonomously, I don't see how this statement could possibly be true. Someone writing a client will need to know how the server is going to return responses to requests. It needs to know what operations the server supports.
I think the "generic understanding of hypermedia" is knowing how to follow links, use the HTTP verbs, and interpret the HTTP status codes.
I think the idea is that if you know to query your account balance with "GET /accounts/12345" and it offers something in its response that looks like an HTML web form or json containing a link to "/accounts/12345/deposits", you could easily infer that a "POST /accounts/12345/deposits" would be used to make a deposit.
How would you know what to POST? Look at the web form and emulate that, or just try it and get a specific error about what fields are missing, ideally with a link to docs.
> It really seems like REST and HATEOAS, using the strictest definitions, really just mean server-side HTML rendering, which is nothing new.
That's actually htmx, which makes sense you got that vibe, because it is the htmx blog and they are highlighting a way to self-document the API with web forms, but REST is connected to the HTTP verbs and HATEOAS is connected to the payload to make REST discovery more intuitive.
As far as I know, nobody really uses this stuff, or at least I haven't seen it in production, but it's been a good idea floating out there for at least 10 years now.
If someone made a HATEOAS linter and a Postman extension, in addition to the obvious htmx endorsement, maybe it would gain some traction.
My understanding is yes, those are all clients.
> If in this instance, "REST client" means an application performing actions autonomously, I don't see how this statement could possibly be true. Someone writing a client will need to know how the server is going to return responses to requests. It needs to know what operations the server supports.
I think the "generic understanding of hypermedia" is knowing how to follow links, use the HTTP verbs, and interpret the HTTP status codes.
I think the idea is that if you know to query your account balance with "GET /accounts/12345" and it offers something in its response that looks like an HTML web form or json containing a link to "/accounts/12345/deposits", you could easily infer that a "POST /accounts/12345/deposits" would be used to make a deposit.
How would you know what to POST? Look at the web form and emulate that, or just try it and get a specific error about what fields are missing, ideally with a link to docs.
> It really seems like REST and HATEOAS, using the strictest definitions, really just mean server-side HTML rendering, which is nothing new.
That's actually htmx, which makes sense you got that vibe, because it is the htmx blog and they are highlighting a way to self-document the API with web forms, but REST is connected to the HTTP verbs and HATEOAS is connected to the payload to make REST discovery more intuitive.
As far as I know, nobody really uses this stuff, or at least I haven't seen it in production, but it's been a good idea floating out there for at least 10 years now.
If someone made a HATEOAS linter and a Postman extension, in addition to the obvious htmx endorsement, maybe it would gain some traction.
> A REST client needs little to no prior knowledge about how to interact with an application or server beyond a generic understanding of hypermedia.
This language always bothered me, 'client' in this case surely means a advanced general intelligence, or 'human', who can futz around with the URIs to try and get what they need. Maybe that's better than CORBA, but it's not the Universal Translator of interfaces by a long shot.
This language always bothered me, 'client' in this case surely means a advanced general intelligence, or 'human', who can futz around with the URIs to try and get what they need. Maybe that's better than CORBA, but it's not the Universal Translator of interfaces by a long shot.
The client is the web browser. Firefox can be built entirely without any knowledge of what hacker news is, and you can still browse hacker news on it.
I think you're providing evidence for their point? HN isn't exactly useful without a person to browse it. "A generic understanding of hypermedia" is easy to say, but may be much more complex in reality to encode into a set of rules that a program knows to follow.
And if we're going to compare "a REST client" as purely the requestor and not the interpreter of the data to something that does JSON RPC calls or graphql, which is often basically REST+, I'm not sure there's any real difference.
And if we're going to compare "a REST client" as purely the requestor and not the interpreter of the data to something that does JSON RPC calls or graphql, which is often basically REST+, I'm not sure there's any real difference.
> HN isn't exactly useful without a person to browse it.
Is any software useful without someone, you know, using it?
Is any software useful without someone, you know, using it?
Hacker News is very useful to Googlebot, and it gets crawled by it every day. It is also useful for people programming Selenium etc to automate using it to collect data.
Conversely, an API is not useful without a human or something automated to use it.
The point of REST/HATEOAS is not to have arbitrary random APIs that can be magically discovered by a random magic application. There must be some agreements and standards there.
OData, GData and AtomPub are good examples of APIs that follow HATEOAS, if you want something that's not HTML+browser.
Conversely, an API is not useful without a human or something automated to use it.
The point of REST/HATEOAS is not to have arbitrary random APIs that can be magically discovered by a random magic application. There must be some agreements and standards there.
OData, GData and AtomPub are good examples of APIs that follow HATEOAS, if you want something that's not HTML+browser.
Your comment is being misunderstood, maybe because of the way you phrased it, but you have a point: a generic client might be able to traverse links of arbitrary data, but it won't know what they mean or why to traverse the links.
Besides a structured data browser for humans, or some kind of transforming proxy, it's hard to see what use cases this is clearly and practically better for.
Besides a structured data browser for humans, or some kind of transforming proxy, it's hard to see what use cases this is clearly and practically better for.
My impression is that the lack of knowledge of what/why is kinda the point: it's the server's job to make the intent clear (via hypermedia), and it's the client's job to faithfully represent that intent to the user. The use-case is therefore related to that of the "semantic web": provide as much expressivity for that intent as possible, and make it as easy as possible for the client to faithfully convey it.
Hypermedia can be domain-specific, which already includes a lot of knowledge about data and operations. In case of HTML client needs to know the semantics of all HTML tags and understand how forms work. JSON-based RMM level 3 API can require knowledge of the schema of domain model and logical names of operations, leaving a lot of business logic to server, e.g. availability of certain operations in current security context. Client can render a button based on whether an operation with given name is mentioned in response or not instead of checking user roles etc.
You are supposed to define custom hypermedia types (instead of application/json which is generic, you have application/foobar+xml).
That's probably the most important post here. Whenever this discussion comes up, people believe that HATEOAS is about magic clients consuming arbitrary JSON APIs. It's not. In HATEOAS the URLs can be arbitrary, but the format cannot.
> a generic understanding of hypermedia
Is doing a lot of work here. Firefox can help me search Google and eBay (and so can lynx and w3m) with "only" a "generic understanding of hypermedia".
Is doing a lot of work here. Firefox can help me search Google and eBay (and so can lynx and w3m) with "only" a "generic understanding of hypermedia".
Client means browser in this context.
Only if hypermedia API is based on HTML/HTTP, which is not necessarily the case.
[deleted]
For me, this feels worse than wikipedia using JSON as an example.
JSON isn't a great HTMl representation, and the wikipedia examples are definitely missing details about how the underlying API is used. But extremely simple HTML just feels worse.
Both pages use a bank account as the example, but my actual bank account has dozens of actions available and is certainly modeled in a way that wouldn't be intuitive for people. Which means we've got an example that isn't easily parseable by computers, because we have mixed labels and data in the HTML, and isn't useful for human beings due to how complex real world entities are.
I genuinely can't tell if this is like monads (which are useful, but often poorly explained) or if this is just a bad idea.
JSON isn't a great HTMl representation, and the wikipedia examples are definitely missing details about how the underlying API is used. But extremely simple HTML just feels worse.
Both pages use a bank account as the example, but my actual bank account has dozens of actions available and is certainly modeled in a way that wouldn't be intuitive for people. Which means we've got an example that isn't easily parseable by computers, because we have mixed labels and data in the HTML, and isn't useful for human beings due to how complex real world entities are.
I genuinely can't tell if this is like monads (which are useful, but often poorly explained) or if this is just a bad idea.
Is it me who does not understand what HATEOAS is?
Always thought that it was basically each server generated page providing the list of links/actions that was allowed from then on.
Basically a lazy, incremental, and fine grained API.
The issue being that it might not be very useful since links have to persist in general on the web. (maybe I misunderstand and it's a non issue?) whereas HATEOAS would be useful if links were never shared: then they could be dynamically generated or updated?
Always thought that it was basically each server generated page providing the list of links/actions that was allowed from then on.
Basically a lazy, incremental, and fine grained API.
The issue being that it might not be very useful since links have to persist in general on the web. (maybe I misunderstand and it's a non issue?) whereas HATEOAS would be useful if links were never shared: then they could be dynamically generated or updated?
HATEOS consists mostly of linking responses ("resources") to each other, as opposed to nesting data. So instead of looking at some nested data, you will follow a link to that data, and so on. You probably won't see it in the wild too often, because RPC rules the world.
I think the idea is to provide your API as some part of the consumer internet. The problem is that a bunch of websites tends to be hard to be navigated meaningfully by a machine, since the machine must be able to process the moving parts in way they do not loose meaning. The idea is that you can simply change a link in a result to be able to split your API in an API that is served by multiple endpoints (e.g. microservices) etc.
Oh makes sense... It's like these books in which you are the hero.
Depending on the use agent and what not, the routes through a given server-rendered website can be different, tailored, per request.
Depending on the use agent and what not, the routes through a given server-rendered website can be different, tailored, per request.
I think this article is focusing a lot of attention on a rather arbitrary aspect of web apps, and suggesting some bad conclusions.
Taking the example from the article... if you want to present bank account information to a user and allow them to take actions on it, then focusing on HTML (and CSS) is a great idea.
However, the data is going to be stored somewhere, and you're going to want to retrieve it and transform it into the desired presentation HTML for your app. In the case of the article, you could say describe these two operations abstractly like this:
presentAccount is just as logically coupled to retrieveAccountInfo in the "hypermedia" case as it is in the "rest", and possibly somewhat more coupled in terms of infrastructure, depending on what's going on at the application server. The application state is determined in exactly the same way.
Of course, there are tradeoffs between running application code server side vs client side. But it really has nothing to do with hateoas and decoupling, and the article doesn't touch on it. (One of the big advantages to running the app server-side is that there's no need for client-side javascript -- this makes the htmx approach -- where the app runs server side but you also need client-side javascript -- a bit questionable, IMO.)
Taking the example from the article... if you want to present bank account information to a user and allow them to take actions on it, then focusing on HTML (and CSS) is a great idea.
However, the data is going to be stored somewhere, and you're going to want to retrieve it and transform it into the desired presentation HTML for your app. In the case of the article, you could say describe these two operations abstractly like this:
retrieveAccountInfo(dataSource) -> (accNo, balance, status)
presentAccount(accNo, balance, status) -> HTML
so the page HTML is determined like this: presentAccount(retrieveAccountInfo(dataSource))
In the "hypermedia" option from the article these two operations run server side in an unspecified way, while for the "rest" option retrieveAccountInfo is implemented as at HTTP GET returning JSON and presentAccount runs in the browser.presentAccount is just as logically coupled to retrieveAccountInfo in the "hypermedia" case as it is in the "rest", and possibly somewhat more coupled in terms of infrastructure, depending on what's going on at the application server. The application state is determined in exactly the same way.
Of course, there are tradeoffs between running application code server side vs client side. But it really has nothing to do with hateoas and decoupling, and the article doesn't touch on it. (One of the big advantages to running the app server-side is that there's no need for client-side javascript -- this makes the htmx approach -- where the app runs server side but you also need client-side javascript -- a bit questionable, IMO.)
What I don't get about these examples is how the HTML from the responses should actually be rendered. I assume no frontend would want to render the HTML as is. Hence they would need IDs on those DIVs to style and place them. But wouldn't that require out of band information too?
> I assume no frontend would want to render the HTML as is.
Well yeah, that'd be pretty ugly on most browsers without some kind of stylesheet, but...
> Hence they would need IDs on those DIVs to style and place them.
...this doesn't really follow from that. Like yeah, that's probably a good idea (even better would be some more specific tags than just divs), but the client has everything it needs to present the data to the user even without that.
The point, I think, is that styling is a separate concern; HATEOAS and REST have more to do with structuring information and interactions with it, and the examples therefore emphasize that instead of a possibly-accidental prescription of some specific styling for that information.
Well yeah, that'd be pretty ugly on most browsers without some kind of stylesheet, but...
> Hence they would need IDs on those DIVs to style and place them.
...this doesn't really follow from that. Like yeah, that's probably a good idea (even better would be some more specific tags than just divs), but the client has everything it needs to present the data to the user even without that.
The point, I think, is that styling is a separate concern; HATEOAS and REST have more to do with structuring information and interactions with it, and the examples therefore emphasize that instead of a possibly-accidental prescription of some specific styling for that information.
This article makes a mistake calling RMM0-2 APIs „JSON APIs“. JSON is data format just like HTML, XML or protocol buffers and it can be used both by true REST or RPC APIs. Focus on JSON is indeed what makes this article ineligible for Wikipedia, it’s just the wrong angle to look at the subject.
I agree with the fundamental principle that "true" HATEOAS is desirable, and that HTML provides it while JSON doesn't.
That said, I don't quite agree with the criticism of out-of-band information. Is the HTML spec not out-of-band information?
Likewise, if they had used an SGML api as the example instead of HTML, would not all the same criticisms of the JSON, for not being HATEOAS, be valid?
There are already many JSON-based APIs on the right path like ActivityPub, JSON-LD, and others. Having to know the specs of these things is no more out-of-band than knowing HTML.
TL;DR: SGML:HTML::JSON:XXXX. If we can all agree on a good XXXX instead of freeforming from just JSON every time, we can get closer to HATEOAS.
That said, I don't quite agree with the criticism of out-of-band information. Is the HTML spec not out-of-band information?
Likewise, if they had used an SGML api as the example instead of HTML, would not all the same criticisms of the JSON, for not being HATEOAS, be valid?
There are already many JSON-based APIs on the right path like ActivityPub, JSON-LD, and others. Having to know the specs of these things is no more out-of-band than knowing HTML.
TL;DR: SGML:HTML::JSON:XXXX. If we can all agree on a good XXXX instead of freeforming from just JSON every time, we can get closer to HATEOAS.
"Is the HTML spec not out-of-band information?"
It isn't. The HTML spec isn't transferred every time a webpage is accessed, so it's not exactly information. Also not really helpful, it's like saying "english" is "out-of-band information" when reading a website written in english.
"Out-of-band" has a very precise meaning here, it comes from the telecom term "out-of-band signaling". There's a wikipedia page: https://en.wikipedia.org/wiki/Out-of-band_data
It isn't. The HTML spec isn't transferred every time a webpage is accessed, so it's not exactly information. Also not really helpful, it's like saying "english" is "out-of-band information" when reading a website written in english.
"Out-of-band" has a very precise meaning here, it comes from the telecom term "out-of-band signaling". There's a wikipedia page: https://en.wikipedia.org/wiki/Out-of-band_data
JSON is fine too, if it carries the same semantic information.
The theory behind HATEOAS was bullshit until LLMs made smart clients plausible. But LLMs don’t need HATEOAS to discover an API. So turns out HATEOAS is still bullshit.
It’s possible that in the age of LLMs this stops being a silly idea, but let’s not pretend it hasn’t up until now been a very silly idea.
It’s a brilliant and beautiful idea that has approximately zero success stories in the real world
From what I understand, Web 1.0 was essentially HATEOAS.
A REST client needs little to no prior knowledge about how to interact with an application or server beyond a generic understanding of hypermedia.
Nothing but a generic understanding of hypermedia? You need some substantial understanding of language and the world to figure out where this link will take you.
<a href="/accounts/12345/close-requests">close-requests</a>
Sure, English is not my first language and financial terms are probably a real weak spot, but I have at best a vague idea what this will do. Can I request to close my account? But why would I need requests for that, plural? So maybe it is not about closing my account but instead a close request is some financial term? If it is, I still have no idea what it is good for.
For consumption by humans, developers poking around in a new API, HATEOAS might be nice. But how on earth are you going to write software that can consume such an API, dynamically discover, understand and use available operations? Maybe you could use ChatGPT to do this. And how are you going to build an UI for this that is any better than what naked objects [1] can deliver if you do not even know which operations the API has to offer?
[1] https://de.wikipedia.org/wiki/Naked_Objects