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.
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.