9 ms·
100% agree, HATEOAS is rather useless for machine-to-machine. And it shouldn't come as a surprise that most APIs decide to not commit to this design constraint.
by pa7x1 5y ago
100% agree, HATEOAS is rather useless for machine-to-machine. And it shouldn't come as a surprise that most APIs decide to not commit to this design constraint.
I prefer to think of real-world APIs as coming in varying degees of RESTfulness depending on the design constraints they have chosen to conform to. Good engineering is about making judicious analysis of the trade-offs involved, if HATEOAS doesn't bring you anything dropping it is the right thing to do.
- Joker_vD 5y agoHATEOAS is somewhat useful even in machine-to-machine: hard-coded URLs in clients are kind of a PITA to support.
- goto11 5y agoWhat is the problem with hard-coded URLs? It is certainly simpler than having to extract the URLs from some other request. If they don't change (and they shouldn't!) I don't see the problem.
- Joker_vD 5y agoWell the problem is exactly that they do change sometimes. And having only one hard-coded URL is easier than having twelve of those. > It is certainly simpler than having to extract the URLs from some other request. It's not extracted from other request, it's extracted from the response to the original request, and using a field from the local struct is not harder than using a global constant.
- goto11 5y ago> Well the problem is exactly that they do change sometimes. Well they shouldn't! And if the API arbitrarily changes URLs around without reason, then surely they might also change the URL for the initial request.
- Joker_vD 5y ago> Well they shouldn't! If you treat them as public interface, they shouldn't, yes. But if you treat them as internal implementation details, they absolutely could. One can also think about it as static vs dynamic dispatch: you make an initial request, you get a vtable of "method name -> method pointer" as a part of response. Or you can hardcode the method pointers and make it the remote server's job to properly chose the appropriate internal endpoint.
- PeterisP 5y agoThe practical problem I have seen with systems (mis?)designed like this is a scenario when the client needs to do action X on resource Y attached to thingy Z - and they already have all the required info to do that action - then they still need to do a request on Z to get the URL for Y and do a request on Y to get the url for action X, which adds extra requests and latency for no good reason. Like, there's no significant difference if there is some original request that has been made, but often that "original" request is otherwise unnecessary and only gets made to enable that extra layer of indirection.
- dragonwriter 5y ago> The practical problem I have seen with systems (mis?)designed like this is a scenario when the client needs to do action X on resource Y attached to thingy Z - and they already have all the required info to do that action - then they still need to do a request on Z to get the URL for Y and do a request on Y to get the url for action X, which adds extra requests and latency for no good reason. If they have “all the info they need”, they have the identity of Y, which in a system designed around REST is the URL, and if Y is a resource, then its URL is the URL for actions on it, and the type of thing it is will tell you what method to use and (where one is applicable) resource to send to accomplish the action. HATEOAS is more than just shipping URLs.
- aaron-santos 5y agoHarded-coded URLs represent a larger API surface area. Hypermedia-driven APIs eg: HATEOAS permit the server to view URLs as an implementation detail. Some people and some problems benefit from APIs with large surface area. Some people and problems benefit from APIs with small surface area. I tend to like APIs with small surface areas because it means I don't have to drag along outdated endpoints across minor versions because the org doesn't want to v2 anything. URLs as an implementation detail makes backwards compatibility much easier. So many times it's been useful to combine or split endpoints as the business needs change without affecting clients. The worst part about using HATEOAS for me has been clients who are used to constructing URLs continue to do so and create a ticket where the obvious first question is "Are you constructing that URL?"
- PeterisP 5y agoEven if the client fetches the URL dynamically, nothing about the semantics of that URL parameters or results can change or the client will break, you can only add extra optional things that the old clients will ignore. All those URLs still very much are part of the API surface area even if they're not hardcoded - their functionality still needs to have out-of-bounds documentation (contrary to the HATEOAS assumptions - "self-descriptive messages" IMHO can work only for syntax but are an unrealistic goal as far as semantics is concerned) and fixed behavior to match that documentation, in all realistic cases the client can't properly interpret the data without programmer intervention if the model changes. So this gives you only the freedom to change the URL naming scheme, but if you want to change the functionality in any way that's not 100% compatible, you still have to drag along outdated endpoints with the old functionality or you'll break clients. But this goes so much in contrast to your comment that it seems that I'm probably misunderstanding you - can you give an illustrative example on how exactly does this allow you to combine or split endpoints without affecting client software that sends/takes data from those endpoints and does some action (business logic) based on that data?
- Joker_vD 5y agoAnd another take on why clients being able to manually craft URLs is bad design: [0]. But prohibitting clients from manually constructing URLs really is not that hard: [1]. [1] https://blog.ploeh.dk/2013/05/01/rest-lesson-learned-avoid-hackable-urls/ https://blog.ploeh.dk/2013/05/01/rest-lesson-learned-avoid-h... [2] https://blog.ploeh.dk/2020/10/26/fit-urls/ https://blog.ploeh.dk/2020/10/26/fit-urls/
- slver 5y agoTo be fair, you need at least one hard-coded URL in your client, don't you? To hit the root entrypoint. And if you have one hard-coded URL... and use it as the root of other URLs, then it's no hard to support than anything. URLs are useful in REST because the API often crosses domain boundaries and company boundaries. One site links to another and so on. Most APIs are not like that. In fact they're only like that when they serve, say, static image assets off a CDN, and guess what, then passing back a URL in your API is self-evident and natural. But not for everything IMHO.
- unscaled 5y agoIf you look at the hydra API example[1] linked by OP, this is exactly what it needs: one entrypoint URL. If your API only needs a single domain name (as over 99% of the APIs are), clients can just have the base URL encoded in a constant or a configuration file. What HATEOAS ostensibly gives you is not the ability to painlessly switch domains, but rather to change your entire URL path structure and even the entire schema represented by your REST endpoints. This feature turns out to be quite useless for most REST clients. Cosmetic changes to URL structure aside, any useful change (in other words - a schema change), will break the client logic, which is still hard-coded to deal with a predefined schema, predefined types of resources and a predefined set of actions that can be performed on each of them. Roy Fielding accurately notes that a truly "RESTful" app should let the engine of its state be completely driven by the server. In other words the client cannot have any _specific_ logic related to "state transfers". If your client is not doing this, like a browser does, than what does it have left to gain from implementing HATEOAS? I'm honestly interested in hearing good arguments, since I haven't heard anything that managed to convince me yet. I've always worked all my API up to level 2 (HTTP Verbs) of the Richardson Maturity model, but I've never felt convinced that HATEOAS is worth the effort. It seems like the majority of HTTP API designers out there have the same opinion. [1]: https://generic.hypermedia.app/ https://generic.hypermedia.app/
- slver 5y ago> What HATEOAS ostensibly gives you is not the ability to painlessly switch domains, but rather to change your entire URL path structure and even the entire schema represented by your REST endpoints. Which would be utterly pointless, because the fact this schema is opaque to the clients means that it's meaningless to the clients. So you have no reason to change it. > I've always worked all my API up to level 2 (HTTP Verbs) of the Richardson Maturity model, but I've never felt convinced that HATEOAS is worth the effort. It seems like the majority of HTTP API designers out there have the same opinion. The "maturity model" is honestly non-sense and Fielding also thinks that. It's kinda like first level to being a bird is flapping your hands, second step is whistling with your mouth... No, you're not any closer to being a bird, you need to be the entire thing for the benefits of being a bird to come about. Trying to stick to the CRUD concept of HTTP verbs is rather harmful. CRUD is a common starting point for a domain's verb structure, but being restricted to it is crippling and results in bizarre obscure semantics or underdeveloped business constraints. I'd say to hell with all of it. I stick to HTTP as-is, and that's it. Also it's telling I think that to this day HTML forms only support GET and POST. Even HTML isn't RESTful I guess. /s
- einrealist 5y agoI disagree. Even if an API is effectively used by a machine, the root cause either is human interaction or it makes sense to also allow human interaction (e.g. for testing, troubleshooting, interactive documentation). HATEOAS can help to define formats that solve both problems.
- slver 5y agoYou can define formats without HATEOAS.
- dragonwriter 5y agoObviously, since defining formats and driving logic through defined and identified-in-band formats is an element but not the whole of HATEOAS. OTOH, applications using pseudo-REST without HATEOAS typically hardcode both URLs and formats rather than relying on in-band identification of both.
- hangonhn 5y agoHATEOAS was a little more useful when the commonly used media was XML rather than JSON. XML has XPath, which I was able to use to find the URLs for the different actions I want to perform, should they ever change. In practice, however, those URLs never changed or were constructed in a very predictable way.