Hypermedia Driven Rest APIs – HATEOAS

hateoas

What is HATEOAS ? (Hate-OAS, Hateous or any other pronunciation)

  • Hypermedia as the Engine of Application State
  • It basically means that your application state should be Hypermedia driven.
  • Hypermedia ?  – Basically hyperlinks to other resources.
  • Which also means that, once a client access a resource, it can use the hypermedia to navigate your resources.

Ok, enough of bookish talks. Lets understand this with an example :

Suppose you are managing a books system where you have following entities :

Book Entity :

class Book {
  String id;
  String title;
  Author author;
  int price;
}

Author Entity :

class Author {
 String authorId;
 String name;
 List<Book> booksWritten;
}

Note: I have used basic data types for the example, ideally we should choose very specific data types based on use case.

Ok, so now we know all our domain entities. Lets see how would HATEOAS api responses would look like :

GET /books/{bookId}

Simple Json Response would look like :

{
 "id": 10,
 "title": "All is Well",
 "price": 100,
 "author": {
 "author_id": 1,
 "name": "Baba Ranchhod"
}

Hypermedia driven API response would look like below :

{
  "content": [
    {
      "id": 10,
      "title": "All is Well",
      "price": 100,
      "author": {
        "author_id": 1,
        "name": "Baba Ranchhod"
      }
    }
  ],
  "links": [
    {
      "ref": "self",
      "href": "https://geeknarrator-book-service/books/10"
    },
    {
      "ref": "author",
      "href": "https://geeknarrator-book-service/authors/1"
    }
  ]
}

 

So basically, when I as a client get hypermedia enabled response, I can navigate the author details just by access the ref: “author”.

Now how would HATEOAS response for Author look like ?

Author :

{
  "content": [
    {
      "id": 1,
      "name": "Baba Ranchhod",
      "books_written": [
        {
          "id": 10,
          "title": "All is Well",
          "price": 100
        },
        {
          "id": 20,
          "title": "3 ways to get rusticated",
          "price": 150
        },
        {
          "id": 30,
          "title": "Dropouts rock",
          "price": 155
        }
      ]
    }
  ],
  "links": [
    {
      "ref": "self",
      "href": "https://geeknarrator-book-service/authors/1"
    },
    {
      "ref": "books",
      "href": "https://geeknarrator-book-service/authors/1/books"
    }
  ]
}

If you closely observe when you make a GET call for an Author (id:1) you get links which are very useful, for example to list all the books from this author you just have to refer books link.

"https://geeknarrator-book-service/authors/1/books"

Similarly, you can think of other examples such as Order Entity, where along with the order details, you also provide a link to the customer or product or payment. The simple idea here is that you should be able to navigate the resources with links to each other just like you see on a HTML page.

Hopefully, this article was able to provide a very basic understanding.

Important Note: HATEOAS comes with added complexity to the API design and implementation. Be sure to understand the use case well before going forward with HATEOAS implementation. There are people who hate HATEOAS, because it is complex and may not necessarily add enough advantages. I personally like this concept and would like to implement it whenever required.

Happy REST API Designing!!

Cheers,

Kaivalya Apte

 

 

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s