Spring Data Rest + HATEOAS

Spring makes it quite easy to create a rest interface. Just include the corresponding boot dependency in your project with standard spring data repositories. That’s it!

Maven Dependencies

All my poms derive from the spring-boot-parent. This takes care off most of my dependency versions:

Each backend module providing a rest interface has additionally the following dependencies:

You see that we must exclude the commons-logging dependency. This had some dependency issues and we use SLF4J for every log output.

Complete examples:

Rest Configuration

Additional Jackson Modules

To use the new and cool Java8 features javax.time and javax.money you need two addional Jackson modules:

In a normal spring boot application, these are automatically used by the jackson object mapper. We are using spring-hateoas and that one uses its own mapper, so we have to configure some stuff manually (see https://github.com/spring-projects/spring-hateoas/issues/333).

Expose id property for all entities

Normally in a spring rest application the id attribute is considered something like an internal information. That should not be given to the outside. The outside / client should only work with URIs.

This is ok in theory, but practically I needed the id in some places (index on my android app etc).

There is no easy way of configuring this, you have to set it for each entity separately! Thanks to reflection (in this case ClassPathScannning) there is a workaround:

Hateoas / HAL

HAL is a way to structure your JSON entries. It separates the content from the links to the related resources.

Spring Hateoas on the other hand is a collection of useful utilities to work with these structures.

The use of HAL has several advantages:

  • All links are in a defined space in the JSON
  • You always have self links (that’s why you no longer really need an id property)
  • You can add own defined links without breaking code
  • Things like paging are supported out of the box (also we still don’t use that feature in Mos Erp)

To activate HAL, the line

is all you need.

Example JSON

GET http://localhost:9303/products:

Under the _embedded section you find the actual product properties. The spring RestTemplate (with HATEOAS support) will automatically map that into your Product class if requested.

In the _embedded section you have a _links sections containing links to related resources (“self” and “product” point to itself). In this case a product belongs to a catalog. You will notice that the catalog uri is not a root uri (e.g. http://localhost:9303/catalogs/1), but a sub resource uri. This is the current way of spring hateoas (like it or not). If this uri returns a 404 (NOT_FOUND) then you know that the relation is empty.

In the root _links section, you can find some relations to the products uri:

  • profile: This is the link to the ALPS profile. Gives you a lot information about the internal structure of the resources (like what properties, what relations).

     
  • search: All findBy* methods in your Repository interface is converted to a search URI in your rest API. This HAL link (http://localhost:9303/products/search) gives you a list of possible searches:

Use of Resource classes and Assemblies

Spring HATEOAS encourages you to use the Resources and ResourceSupport classes. They already contain links.

But for an easy start you can just use the spring-data-rest mechanism and use your domain classes directly in your rest interfaces.

In the integration tests we sometimes had to use Resources and ResourceAssemblies, but now since we save URIs in our datastore for non-module resources, we no longer need that.