I really struggle to see where HATEOAS can be used. Obviously not for machine to machine uses as others have pointed out. But even for humans it would lead to terrible interfaces.
If the state of the resource changes such that the allowable actions available on that resource change (for example, if the account goes into overdraft) then the HTML response would change to show the new set of actions available.
So if I’m in overdraft, some actions are not available? Which means they are not shown at all? How can a user easily know that there are things they could do, it it wasn’t for the fact that they are in a specific state? Instead of having disabled buttons and menus, with help text explaining why they are not usable, we just hide them? That can’t be right, can it? So how do we actually deliver a useable UX using HATEOAS?
Or is it just meant for “exploration”, and real clients would not rely on the returned links? But how is that better than actual docs telling you the same but much more clearly ?
How does HATEOAS deal with endpoints that take arguments? E.g. I have an endpoint that merges the currently viewed resource with another one? Does it require a new (argumentless) endpoint showing a form where one can enter the second resource? Wouldn’t it be quite inefficient if you have to now do two (or more) requests instead of just one?