I have been reading a lot about the potential benefits if I were to convert my existing Restful web services to be as HATEOS as possible. I understand the importance in providing links in the payload to reduce the consumer's burden in remembering the next valid available actions. However, I can't seem to wrap my head around how it will help the consumer of my Restful web services in reality.
To illustrate, I take this example from Rest In Practice book about making a coffee order:-
<order xmlns="http://schemas.restbucks.com">
<location>takeAway</location>
<item>
<name>latte</name>
<quantity>1</quantity>
<milk>whole</milk>
<size>small</size>
</item>
<cost>2.0</cost>
<status>payment-expected</status>
<link rel="payment" href="https://restbucks.com/payment/1234" />
</order>
Basically, this allows the consumer to make a payment defined by the <link>
tag. However, in reality, the consumer still needs to know all the semantics of that web service call, for example, what method (POST or PUT) to use, what request parameters to use in the payload in order to make the payment, etc... in another word, the consumer still needs to rely on the WADL documentation to know how to make invoke this web service successfully. These tags probably make more sense if they are all using GETs on one specific item. Otherwise, I really don't see much benefits in defining the links here... apart from the fact the consumer knows what actions they can invoke next, and then refer to the WADL to determine how to invoke it correctly.
My next concern is the possibility of ending up with a very heavy payload with all the <link>
tags. For example, if a GET on /projects/1/users returns all the user information that belong project 1, I assume I will end up with the following tags:-
<project>
<users>
<user id="12" name="mike" ... />
<user id="23" name="kurt" ... />
<user id="65" name="corey" ... />
</user>
<links>
<link rel="self" href="http://server/projects/1/users"/>
<link rel="create_user" href="http://server/projects/1/users"/>
<link rel="get_user_mike" href="http://server/projects/1/users/12"/>
<link rel="get_user_kurt" href="http://server/projects/1/users/23"/>
<link rel="get_user_corey" href="http://server/projects/1/users/65"/>
...
</links>
</project>
If a project contains say, 500 users... wouldn't I have 500 user links in the payload? Otherwise, what is the best approach in redesigning my web services to handle this situation? Or is this acceptable in real world?
Any thoughts or suggestions are greatly appreciated here. Thank you.
HATEOAS is just one of the aspects that adds difficulty to a REST architecture. People don't do HATEOAS for all the reasons you suggest: it's difficult. It adds complexity to both the server-side and the client (if you actually want to benefit from it). HOWEVER, billions of people experience the benefits of REST today.
Using HATEOAS allows an API to clearly define a control logic that is available at the client-side. This enables them to follow links embedded in the API resources instead of having them manipulate URLs. This decouples clients from the URL structure so that changes don't end up hurting integration.
With HATEOAS, a client interacts with a network application whose application servers provide information dynamically through hypermedia. A REST client needs little to no prior knowledge about how to interact with an application or server beyond a generic understanding of hypermedia.
HAL is a simple format that gives a consistent and easy way to hyperlink between resources in your API. The HAL format is strictly coupled to HATEOAS. The main target of HATEOAS is to decouple the API Consumer from the paths used in the API.
To think of why it's the right thing to do, imagine your API without a HATEOAS approach: you'll have to publish every single possible URI scheme in your documentation (or in your WADL, if that's your thing), and from that point on you cannot change them without breaking your clients.
In essence, your clients will be inextricably coupled to your choice of URI layout. That's a level of coupling that you can easily avoid by just documenting where the links are in your media types rather than documenting what the links look like as well.
That said, it might be OK for your application's needs to take that approach, and that's fine. Just keep in mind that you'll be stuck with your URI layout for a long, long time. You'll be in good company though.
For your particular example, I think it makes sense to go back to HTML. If you display a list of 500 resources in HTML, would you include a link to each resource, so that users can get more information? You probably would. A REST API is not much different - if you return a list of 500 resources, you need to include 500 links, so that users can get more information about each resource.
Expecting clients to build up URLs based on some IDs or names would be like asking users to manually type URLs in the browser's address bar.
Here is a very good article (dead link) about this, in particular:
Just like HTML files link to each other with tags, or just like XML files link to each other with XLink, all state transfer has to be done solely as a reaction to a link found inside of a representation
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With