RESTful Services – Why Implement HATEOAS with a Self-Relationship Link

hateoashttpidentityrest

I'm learning about HATEOAS and I noticed that every implementation always seems to implement a self-relationship first. For example a common response object might look like

{
  title: "The Wonderful Wizard of Oz",
  author: "L. Frank Baum"
  links: [
    {
      rel: "self",
      href: "www.foo.com/book/1234"
    },
    {
      rel: "author",
      href: "www.foo.com/author/4321"
    }
  ]
}

Why is the self relationship always there? It seems utterly useless to me. As a client who just made the request to get the response object I would obviously know the URL to get the object. Why is it presented?

Best Answer

The self link is also used for embedded entities where it can be used to navigate to the proper entity. See this HAL example:

{
    "_links": {
        "self": { "href": "/orders" },
        "curies": [{ "name": "ea", "href": "http://example.com/docs/rels/{rel}", "templated": true }],
        "next": { "href": "/orders?page=2" },
        "ea:find": {
            "href": "/orders{?id}",
            "templated": true
        },
        "ea:admin": [{
            "href": "/admins/2",
            "title": "Fred"
        }, {
            "href": "/admins/5",
            "title": "Kate"
        }]
    },
    "currentlyProcessing": 14,
    "shippedToday": 20,
    "_embedded": {
        "ea:order": [{
            "_links": {
                "self": { "href": "/orders/123" },
                "ea:basket": { "href": "/baskets/98712" },
                "ea:customer": { "href": "/customers/7809" }
            },
            "total": 30.00,
            "currency": "USD",
            "status": "shipped"
        }, {
            "_links": {
                "self": { "href": "/orders/124" },
                "ea:basket": { "href": "/baskets/97213" },
                "ea:customer": { "href": "/customers/12369" }
            },
            "total": 20.00,
            "currency": "USD",
            "status": "processing"
        }]
    }
}

The only rationale I could think of for having self links on top-level entities is that if you enter the service at some arbitrary entity, the self link gives you information about your context in the service. In the example above if somebody gave me a link to http://example.com/myservice/special/dev/2017/admins/2, the self link relative to the service root (/admins/2) would be useful for finding the root of the service and understanding that there are probably more admins, etc.

Related Topic