Search code examples
apirestasp.net-web-apirestful-urlhateoas

Flexibility of HATEOAS


I am trying to learn how to better craft REST API, I have read about HATEOAS, but cannot fully understand all flexibility of it.

Can someone explain why is it flexible.

Lets consider PayPal HATEOAS API

Here an example of array of links

[
  {
    "href":"https://api.sandbox.paypal.com/v1/payments/payment/PAY-6RV70583SB702805EKEYSZ6Y",
    "rel":"self",
    "method":"GET"
  },
  {
    "href":"https://www.sandbox.paypal.com/webscr?cmd=_express-checkout&token=EC-60U79048BN7719609",
    "rel":"approval_url",
    "method":"REDIRECT"
  },
  {
    "href":"https://api.sandbox.paypal.com/v1/payments/payment/PAY-6RV70583SB702805EKEYSZ6Y/execute",
    "rel":"execute",
    "method":"POST"
  }
]

I understand that we can make a request, for instance in case of this example for payment information.

There are some questions

  1. Why do we need self as type of rel, when request is made by the application it already knows the full url of this resource , am I right ? Why do we need to duplicate it in links array ?

  2. Whee is flexibility ? In this example there are three (two without self) rel types. How does application know all this types ? They should be hardcoded anyway in code and if for example new rel type was introduced we still need to add logic into the client code to handle such type of rel, so as a result we need to handle types of rel or if API responses doesn't follow HATEOAS principle write logic to make new requests.

Am I wrong ?

Please explain the main idea of this. I would be grateful for any help.
Thank you.


Solution

  • I'm going to answer these in reverse order, because I think the answer to (2) will help clear up (1).

    Yes, most client applications will need to know how to handle the set of possible rels. The idea is to insulate your clients from needing to know specific URIs. If clients hard code or manually track URIs, then the server cannot ever change the path to anything without breaking clients. If the client tracks rels, then the API has some flexibility to change what its endpoints look like. The client, using rels, doesn't care that a URI has changed.

    The reason to keep a self rel around is so that you can use it later. Let's say you get a collection of resources from some other rel. You display them all on the screen. When a user wants to update one of those resources, how do you do it? Pop up a dialog with all the data, and after they update and hit save, you do a PUT on the self URI to update the resource.

    Also, sometimes it's convenient to respond to clients with a lightweight resource. So, say you ask for a collection of 200 things. Rather than returning 200 full-blown resource, it might make sense to return 200 objects which just have a name property and a self rel. The client displays the 200 names, the end user picks one, and then the client does a GET on the self rel to pull down all the data for that one specific resource.