A RESTful learning curve: nouns, verbs, HATEOAS and ROCA - codecentric AG Blog

:

I really don’t claim to be a REST expert, but I learned a few things during the last months that I want to share with you. Some things might be trivial for people already working with REST a lot, good for you then, but I guess there are a lot people like me out there:
People that know the basic principles of REST, maybe have used or extended a RESTful web service here and there, but never had to design a resource from scratch.

REST is all about nouns, not verbs

This is maybe the most trivial subject of this post: there is always some Entity behind an URL, not an action. If you have resources for manipulating a customer entity, they could look like this:

…/customers

for the list of all customers. A GET would return all customers, a POST would add a customer to the list, a DELETE would delete the whole list and a PUT would replace the whole list.

…/customers/123

for the customer with id 123. A GET would return the customer, a POST doesn’t make sense, a DELETE would delete the customer and a PUT would update or insert the customer.
On this level, it’s well understood. But now we have some kind of action we want to perform on the entity. Maybe we need to approve our customer before he can buy stuff. I saw RESTful services offering a URL like this, designed to offer the functionality of approving the customer:

…/customers/123/operation/approve

or

…/customers/123?operation=approve

It’s always good to lean back and think of the four HTTP methods GET, POST, PUT and DELETE: what do they mean for the designed URL? What exactly do I PUT on …/customers/123/operation/approve? What do I GET from it? Some kind of flag? You quickly realize that there is something wrong with this URL. If it is a flag in the form of ‘approved’, it should be part of the customer, and the client may simply set this flag to true and PUT the whole customer. If there is some business logic necessary for the approval, the backend has to detect the state transition and execute the business logic. If there’s more to the approval than just a flag, you’re free to design a new sub resource …/customers/123/approval. You may then PUT approval information to that resource, and use GET to get the approval information for a customer.

Clients should not build up URLs – the HATEOAS principle

Let’s take a look at how the WWW works when we surf it:

We usually type in one URL, our landing page. It gets rendered with a lot of links in it, and then we follow one of the links, read the page, follow some other link and so on. We usually type in an URL just once, and the rest is following links.

And how does a client of a big part of all RESTful web services work?

It constructs an URL for a resource, maybe …/customers for getting all customers, and then does a GET on this link. The client receives a representation for this resource, let’s say a list of reduced customer data with just the most important fields and an id. It then uses the id to construct a new URL (…/customers/{id}) for getting the detail information on the customer.

Have you noticed the difference? It’s like typing in the URL whenever you want to see a new page. The client has to know all resource URLs. That’s not RESTful.

HATEOAS is an abbreviation for Hypermedia as the Engine of Application State. It’s not just an add-on to the REST architectural style, it’s essential. For our example above it means:
Instead of including just the id of the customer in the list of customers, we include a link to the full customer resource with a specific relation name. The client can now follow that link if it wants to retrieve the customer. The client just needs to know what kind of relations are to expect, but the link itself is under full control of the server. That means the server may change its URLs without breaking the client, as long as the entry point stays the same. If you want to read more on this topic with some more theoretical background, follow this link to one very interesting blog post by Roy T. Fielding: REST APIs must be hypertext-driven.

If you want to build a true RESTful web service, you face the problem of creating those links. Oliver Gierke’s library spring-hateoas solves this problem for Spring MVC. It introduces a Resource class which is a wrapper for a domain object and a collection of links. The Link consists of a relation name and an URL. The library offers support for creating a Resource object for a given domain object, and it offers support for creating Link objects without repeating request mappings. Normally you define some request mappings in controllers on the server side, and you surely don’t want to repeat yourself.
This way, processing a REST request becomes a three-stepped-process:

  1. Do business logic and return the result as a domain object.
  2. Create a resource object via enriching the domain object with links.
  3. Create the presentation for the resource object and give it back to the client.

If you’re interested in more details, take a look at this video presentation of Oliver at Øredev Conference.

REST is not just the new SOAP – the Resource-oriented Client Architecture (ROCA)

When we talk about REST, we almost always talk about RESTful web services. They are widely used in machine-to-machine communication, and when they are used in the web context, we often talk about fat web clients, single page JavaScript clients and the like, using those services to get their data.

Why?

The static web of course follows the REST architectural style, but during the last decade we learned that the static web and web applications are two totally different things. Well, they don’t. At least they don’t have to be. It’s possible to build web applications that follow the REST architectural style, and you gain a few advantages. Here’s an incomplete list:

  • No session that may expire.
  • Bookmarkable URLs for everything.
  • Easier integration of different applications.
  • Applications don’t have to become big monoliths, it’s easy to split functionality up.
  • Back and forward buttons always work.

Of course, there are some things you cannot do. You’re maybe not able to use your favorite web framework, because every framework that hides HTTP from the programmer is not really suitable for such an architecture, and yes, that includes JSF, GWT and some of those smart new JavaScript libraries.
If you want to learn more about ROCA, take a look at its web site, or go to a talk of one of its initiators. It’s always inspiring to hear Stefan Tilkov talk about it.