When we talk about creating RESTful services using hypermedia we often get into discussions why the links are necessary. Why not simply publish a list of available URI:s and the client can code directly using these links? Won’t there be much overhead in putting links into every response? We think that REST level 2 services are very useful and we will avoid the discussion if hypermedia is required to be RESTful. In this blogpost we will try to explain why we think a hypermedia API (level 3) is useful and have practical advantages.
It has been a really good and inspiring JavaOne this year and our session Effective HATEOAS with JAX-RS was well received. You can already download the slides or view the presentation video! This is the first post in a series where we will explore hypermedia APIs in general but also how to implement this style in Java using JAX-RS.
We need to start by looking at how an application using a hypermedia API looks like. In this example we will investigate how a simple webshop for e-books would look like if it was using a RESTful hypermedia API. The things the customers of the site can do are:
- View details about the books (title, author, description etc)
- Browse for books
- Buy book
- Download book
Since the books are downloaded by the customer there is no need for shipping, inventory etc that typically complicates a webshop. If the customer has bought the book they can simply download it! All this is to simplify the example so that we can focus on the hypermedia and not the complexity of the domain.
The resources of the API and their relationships are shown below. The relationships are rel attributes which are used so that a client program can understand what the link means. We will describe this in more detail in further blog posts.
We imagine that a customer can access the webshop either using a normal web UI or using a mobile client with in-app purchasing. The customer might go through the following steps:
- Retrieve the root resource and decides to follow the link to the available books
- Retrieve the list of available books. Besides a list of links to books this also contains the most recent books. The customer decides to navigate to follow the link to book 123
- Retrieve book 123 which describes the book including title, author, price etc. Depending on if the client has bought the book there is a link to either purchase or download the book. Since the customer does not own the book, there is only a link to purchasing the book. The customer decides to purchase the book.
- The customer completes the purchase (probably using POST). The representation includes a link to downloading the book. The customer decides to download the book.
- Retrieve the book in epub format.
Lets analyze this from the client perspective:
- URI naming convention: The actual URIs are irrelevant. A client couldn’t care less if they are nouns, verbs or opaque identifiers.
- Navigation: Without the links the client must implement logic for building links. If you put this code inside your iphone or android clients you cannot change the URI structure on the server without breaking existing clients.
- Behavior: If a link is present the client can follow the link. A client application does not have to repeat the business logic for deciding if a book can be purchased or downloaded. This means that we can implement a free download campaign simply by including the download link and no change on the client side.
This means that as server developers building a REST API we can use hypermedia to:
- Choose a URI naming scheme that fits whatever framework or coding conventions that we find useful
- Change business logic in a single place!
- Be able to update our URIs without completely breaking old clients. Sure, we might break some bookmarks, but the clients will still work. (Notice although possible it might still be a bad idea)
Another subtle advantage is that since the server must provide all the links that the clients can follow this means that the server developers must know and understand the kind of usecases that the clients have. In a traditional API without hyperlinks you only expose information that a clients has requested and don’t care what it is used for. In a hypermedia API you need to be aware of the workflow and guide the client by providing links. In our experience this encourages more communication and understanding between client and server developers.
Hopefully, we have explained the benefits of using a hypermedia API. Now we have a few weeks of vacation in California. Once we get back we will follow up this post with more details and how you can implement this is Java.