...Its ludicrously bloated and part of the reason why no one does "real rest."
Actually, it doesn't need to. The owner object would only have invoice IDs. The invoice collection resource would be discoverable through the root endpoint through the same process used to discover the pet and owner collection resources.
In fact, the owner doesn't need to have any invoice information at all. The invoice collection endpoint can simply be queried to find an invoice related to the pet and/or owner.
> ...Its ludicrously bloated and part of the reason why no one does "real rest."
Actually it isn't, and the main reason why "no one does real rest" is because web API clients are required to perform content discovery, which is more complex than simply using hard-coded URLs/URL paths.
Of course this complexity is only apparent and superficial, as having to support a myriad of API versions ends up with a simple solution that due to all the technical debt that piles on rather quickly is far more complex and error-prone and unmaintainable than the approach required to do REST.
> web API clients are required to perform content discovery, which is more complex than simply using hard-coded URLs/URL paths
You mean using Hypermedia As The Engine Of Application State is cumbersome and why people don't do "real rest"? Yes. I agree.
HATEOAS is neutral as to resource representation; you could have the invoices collection and all the individual resources within the (or one of the; resources don't need one and only one representation) owner resource representation.
If the collection or invoices can be accessed as individual resources (which, again, HATEOAS is neutral about), they should have their own URLs, but that doesn't prevent them from being incorporated in the parent resource representation.
Naive orthogonal CRUD on (the equivalent of) base tables of a normalized DB design is not a requirement of HATEOAS or REST, and it's often bad API whether or not you are aiming for REST. Its the a strawman every one beats on about REST, but it's got nothing to do with REST.
Well, yes, you need to know the semantics of the relationship, but not for parsing, because he content-type plus, where needed, internal data within the resource representation more specifically identifying the subtype should tell you what you need to know about handling the representation.
That's HATEOAS.
If you’re interacting with the api then it’s extremely likely you’re not going to write code that will automatically follow reference links and attempt to parse them dynamically.
You will need to know what fields are in the end point how they represent data (iso 8601 for dates? Unix timestamps?).
You’re substituting documentation with asking the api consumer to explore and discover and assume.
But you've documented how your API works anyway, right?
And let's not kid ourselves, much of our world runs on APIs that would really deserve the "bad design" handwave, end of the day that's often an aesthetic question.
However, you can have it both ways: in the customer response, use
"invoices": "/customer/7sn2J/invoices"
and have the server 307 redirect to "/invoices?customer=7sn2J", or whatever you prefer.
More fundamentally, I think it's trying to solve a smaller problem in the face of a much bigger one, you still need to know what the response of any given endpoint is going to be. Just because they've passed me a link, doesn't me I don't need documentation on what endpoint that link points to. I still need to know that the owner is a link to the people endpoint so I can properly parse that result. That in turn requires just as much documentation (IMO) to describe the relationships as it would to properly document your URI templates.
Obviously, the primary reason to use links over ids is to give the developers of the API more control over changing things like routes and Ids and whatnot, but I feel like it is a bit disingenuous to make it out to be a much better user experience or something, since it really isn't.