Image Blog Beyond REST How to Build a HATEOAS API
June 3, 2014

Beyond REST: How to Build a HATEOAS API in Java

Java Tools
Java Application Development

These days, it's fair to say that the REST architectural pattern is the reality of the modern web development. In 2007, an InfoQ article showed how REST was growing based on a "small, but very vocal minority" who "claims there is another way". Fast forward to 2014 and we cannot even think about building a new API without using it. Period.

In this post we'll talk about what makes the REST pattern unique and somewhat misunderstood: hypermedia controls. We'll introduce you to the hypermedia design module, and then we'll build a HATEOAS API in Java. We'll be using Spring MVC, Jersey (JAX-RS) and VRaptor to check if they support HATEOAS (Hypermedia as the Engine of Application State) concepts or make your life harder at delivering the proper REST API.

When we're finished, you’ll see how important a proper API structure is and how a HATEOAS API in Java can help you client side be more decoupled from the rest of the services, something we’d all enjoy...

(For more on hypermedia controls, check out Jan Kronquist's presentation from the 2014 GeekOut Estonia conference.)

image of rest area ahead sign

REST API Maturity Model

Recently, we have seen a lot of buzz about the REST API maturity level. These levels, as described by Martin Fowler in Richardson’s Maturity Model, are still under discussion, so not even all libraries and implementations are aligned with those. Here’s what is looks like:

graph of REST API maturity levels

Some APIs are closer to the maximum level offering hypermedia controls, and some are far away from the dreamed "REST Glory".

To achieve the 3rd level of maturity, your API must implement the HATEOAS concept. To the best of my knowledge, this acronym has no common pronunciation yet. Which is a strange situation for me as a foreigner: how can I look smart talking about it when I don't know how to pronounce it? The best guess is “HA-tee-oh-az”.

In short, HATEOAS says that your API must be like the world wide web, meaning navigable by links, which will be accessed by a representation called rel, which can for example be the WWW link name. HATEOAS also says that all the actions available for a given resource, all its state transitions, plus all the relations between resources, must be in link form.

With this approach, your API will be more self-documented and the clients will be less coupled with it, because they must only know the link name, rel, and not the link address itself. You’ll be free to change your URLs without fear of breaking your clients.

Related reading on API first >>

Diving Into the World of REST Libraries

With these concepts explained above, let’s now talk about the main article's objective: how can you build a mature API with Java? Are there any frameworks ready to help us to build this proper REST API?

With these questions in mind, I've chosen 3 frameworks to build a sample API application and check if they are really ready for the REST API glory. Our competitors in this challenge are: Spring MVC, Jersey and VRaptor.

Spring, Jersey and Vraptor logos

To make the comparison fair and easy, I decided to build a sample application to put HATEOAS concepts in practice and see if those 3 frameworks can help us to do it. You can check out the source code on Github and, if you wish, you can fork and make your own tests.

The application is simple and is not intended to be fully production-ready. I decided not to build a full REST API, with a CRUD and actions that change states, which is something we all know can be done. What we want to know is do these frameworks help us to expose resources in order to build a HATEOAS-like API?

Spring MVC

Spring always been a source of innovation. They changed the way we do Java enterprise application development and forced Java EE specifications to be more productive. I still see them like that, and these feelings aren’t different when we talk about APIs.

Spring MVC was always a good choice for building a REST-like API, but we now know that not all APIs are proper REST, don’t we? When we talk about HATEOAS, Spring has really great support via the Spring-HATEOAS project, which is a Spring MVC extension that helps us to build HATEOAS style APIs.

To build an API you must know a bit about four things:

  • controllers
  • resources
  • links
  • how to build these links 

A controller is just an ordinary Spring MVC controller and is a component that will somewhat control the interactions between HTTP requests and our application logic. It’s nothing new if you have already used Spring MVC or any other Java web-application.

A resource is a component that will contain basic properties: Strings, numbers and tiny types; and a link to related resources and actions that can change the current resource's state.

Every resource must at least have a link named self that points to the current resource itself. We can treat a resource as an entity, because it has properties and can be related to other entities. The resources will be our model, when talk in the MVC terms. In Spring-HATEOAS you can extend your resources from the ResourceSupport class. ResourceSupport has already implemented support for adding links, so your job is to worry only about properties and what exactly to build those links from.

If resources are made of just properties links, there should be an easy way to build them. With Spring-HATEOAS we can build a link using any LinkBuilder implementation. However, I advise you to use the ControllerLinkBuilder, which can build your links using only a Java DSL. Your link will point to controllers and their methods and, if needed, you can refactor those methods and the link construction code will be refactored too.

With the ControllerLinkBuilder.linkTo method, you can create a new instance of a link and then decide which form of build construction you want to use. If you decide to use the linkTo that points to a Method parameter, you can use the ControllerLinkBuilder.methodOn method, which will help you build a link that points directly to the public path of the current resource. Your link construction will look like this:


It’s a very cool and easy way to build links, and I really hope you use it! I assure you that it will help you be more productive and generate less bugs, especially if you are building links to endpoints in your own API.

But Spring MVC is not perfect: in its out-of-the-box configuration, you need to build a resource for each entity that you want to expose. It is not hard, but it's sweaty. And while JSON support is very good, other formats do not come out-of-the-box. Additionally, I had no success trying to make JAXB support work. If you know how to do it, tweet at me @jrdalpra. That's the only annoying thing I have found in Spring-HATEOAS.

Jersey (as the JAX-RS Reference Implementation)

For the ones that love the standard approach, I decided to test if JAX-RS is a good choice for building a HATEOAS application. I used Jersey, the reference implementation of the JAX-RS, to do just that...

Jersey, as its documentation says, is a framework that extends the specification and introduces its own API that intends to improve your productivity and the quality of your new API. In terms of a HATEOAS API the Jersey framework has no standard ways to make it easier to build, but I decided to use only the standard API, so you can see if it fits in your current reality. This will also make testing our sample application with other JAX-RS implementations, like RESTEasy for example, much easier.

As in Spring, to build a HATEOAS API you must use controllers, resources and links. Nothing is very different here. But JAX-RS has no basic classes for a resource or a collection of resources, so you have to build your own abstract classes.

If you already work with JAX-RS, then you know that to build a controller class you only need to create your class and annotate it with @Path (pretty easy). After that you create methods that return some kind of a Response to the caller. JAX-RS comes with builders that make creating a response a breeze.

Your resources will be just POJOs with some JAXB annotations to make your life with XML or JSON binding easy. Make sure to use only simple properties and use links for complex relationships, and don’t forget to use a collection of links in your resource class. For the JAXB binding, there's a trick here: use the Link.JaxbAdapter into the @XmlJavaTypeAdapter annotation above the links collection.

To build your links, JAX-RS has three really helpful classes: UriInfo, UriBuilder and Link. The UriInfo class is injected in your controller, via a @Contextannotation, and is used to obtain an UriBuilder object. I used the getBaseUriBuilder method at UriInfo to obtain the application ROOT URI. Then you can call the path method of the UriBuilder and pass the controller class and the method name to build the URI. You can also pass a query param to it. This is all to configure the UriBuilder that will be passed to the Link.Builder object created over the fromUriBuilder method. After that, define the rel name and call the build method, passing some parameter if needed. Your can see the sample code here.

Against JAX-RS I have these points: building links using controller classes and methods names as Strings can produce bugs, especially when you change the method name when refactoring. Besides that, you also have to fight with JAXB to produce some decent XML/JSON output. The need to declare what your controller or method will produce is annoying: can't we negotiate the content with some general configuration or an interceptor of some kind?

If you already use JAX-RS in other APIs, then you can maintain your knowledge and take a step forward to the HATEOAS API. Additionally, some of the mentioned issues can be solved with your own JAX-RS extensions (or third-party ones if you find any).


Confession: I think that VRaptor is the most spectacular framework that I’ve ever used. Why? Because it's simple and, consequently, easy. It's also extensible. So you can override its behavior with your own implementation. How cool is that? And for those who like CDI, the 4th version of VRaptor will use it to control dependency injection and component lifecycles.

VRaptor also has very extensive documentation that is presented in a cool form. It is divided into little tutorials that will guide you through the framework. This is why it was easy for me to decide to use this framework, which I already knew had support for HATEOAS, even before it became a buzzword. The version used is VRaptor 3.5.3.

To build a HATEOAS API with VRaptor, we will use an extension of the framework called Restfulie. In addition to Java, Restfulie also supports for Ruby and .Net and has a very easy client API for all supported platforms.

The structures that you must use to build your API are not different from the previous frameworks: you'll need a controller, a resource and the links, which VRaptor calls Relations.

The controller is a normal VRaptor controller, so just use the @Resource and configure your methods with @Path and the proper HTTP verb annotation, like @Get. It actually is as simple as it sounds. You can view some sample code here.

To build the resources you need to just create a POJO that implements the HypermediaResource interface and use the configureRelations method to build your relations using the RelationBuilder parameter.

The RelationBuilder interfaces offers to us some method that will help us to build our relations. The syntax is very straightforward and you'll have no problem using it. As with Spring-HATEOAS, VRaptor offers a method that helps us to build links to other controllers in the same application. Your code will look like this:

  public void configureRelations(RelationBuilder builder) {
        builder.relation("states").uses(StatesController.class).listByCountry(entity, 0, 10);

Building a collection of the resources is easy as well. You just create a wrapper that contains the collection and make it implement the HypermediaResource interface.

It is somewhat annoying that VRaptor’s HATEOAS implementation uses XStream as the serialization mechanism. But it is historically justified, since XStream was the best option when Restfulie came out.

The only bad thing about VRaptor is that Restfulie will not be bundled with version 4, rather it will be present as a separate extension. At the time this article was written, Restfulie was not supported yet in the newest VRaptor's release.

Final Thoughts

If you’re a developer+ and want to build a HATEOAS API, then my message for you is this: there are alreadt some great tools that can help you achieve your goal. All the libraries that I used for this blogpost can make your job easier and guide you to the dreamed maturity of your API.

Are you a Spring framework/tools lover just like myself (and apparently as much as 40% of developers)? Do you need a full-stack tool that will help you to build everything from APIs to complex integrations? Then use Spring MVC and Spring-HATEOAS. The Spring team at Pivotal has done a great job at building this extension and you won’t regret using it.

What if you, or your boss, prefers to use standard approaches? Then try JAX-RS without fear: with just a little effort you can get things done. Why do you have to change everything just to build an API? Don’t throw away your knowledge about all Java specifications that you already use, and just go for it.

What about if you just want a really simple way to build APIs, using a mature tool that has been in the market for a long time? I suggest you use my favorites, VRaptor and Restfulie. It’s simple and based on conventions over configurations. You'll get things done in a short period of time and you'll see how easy it is to use VRaptor.

Thanks for reading my article, which I hope was helpful. Regardless of what library you choose, you should be fine. If you have any questions, feel free to put them into the comments section below, or tweet to @jrdalpra.

Additional Resources

Looking for more Java resources? Find the latest resources on our site.

Looking for additional reading? Our recent microservices frameworks article is an interesting one -- be sure to check it out!

Read the Article