HateOAS

Rest levels

Model of restful maturity used to help explain the specific properties of a web-style system.

Level 0

The starting point for the model is using HTTP as a transport system for remote interactions, but without using any of the mechanisms of the web.
We publish a document on how to use our API. We declare only one endpoint and do all the communication through this endpoint.

Level 1

Now rather than making all our requests to a singular service endpoint, we now start talking to individual resources or endpoints. One specific for every action we want to do.

Level 2

Uses all the HTTP verbs as closely as possible as to how they’re used in HTTP itself. This are GET, POST, DELETE

Level 3

Introduces HATEOAS (Hypertext As The Engine Of Application State). It addresses the question of how to get from a list open slots to knowing what to do to complete our action.

Reference

https://www.martinfowler.com/articles/richardsonMaturityModel.html

HATEOAS

The point of hypermedia controls is that they tell us what we can do next, and the URI of the resource we need to manipulate to do it. Rather than us having to know where to post our appointment request, the hypermedia controls in the response tell us how to do it.

The first post is the same as one of level 2

POST /slots/1234 HTTP/1.1
[various other headers]

<appointmentRequest>
  <patient id = "jsmith"/>
</appointmentRequest>  

But the reply contains a number of hypermedia controls for different things to do next.

HTTP/1.1 201 Created
Location: http://royalhope.nhs.uk/slots/1234/appointment
[various headers]

<appointment>
  <slot id = "1234" doctor = "mjones"   
    start = "1400" end = "1450"/>
  <patient id = "jsmith"/>
  <link rel = "/linkrels/appointment/cancel"
        uri = "/slots/1234/appointment"/>
  <link rel = "/linkrels/appointment/addTest"
        uri = "/slots/1234/appointment/tests"/>
  <link rel = "self"
        uri = "/slots/1234/appointment"/>
  <link rel = "/linkrels/appointment/changeTime"
    uri = "/doctors/mjones/slots?date=20100104&status=open"/>
  <link rel =  
    "/linkrels/appointment/updateContactInfo"
        uri = "/patients/jsmith/contactInfo"/>
  <link rel = "/linkrels/help"
        uri = "/help/appointment"/>
</appointment>

One obvious benefit of hypermedia controls is that it allows the server to change its URI scheme without breaking clients. As long as clients look up the “addTest” link URI then the server team can juggle all URIs other than the initial entry points.

A further benefit is that it helps client developers explore the protocol. The links give client developers a hint as to what may be possible next. It doesn’t give all the information: both the “self” and “cancel” controls point to the same URI - they need to figure out that one is a GET and the other a DELETE. But at least it gives them a starting point as to what to think about for more information and to look for a similar URI in the protocol documentation.

Implementation

Spring HateOAS

Structure

Until now we had 2 beans for the representation of an object: Entity and Dto.
Right now we have one more: Resource. This is the HateOAS representation which we’ll give back and which will directly save the links added. It must extend ResourceSupport.
A mapping will be needed btw. the entity / dto and the resource.

// .scheme removes "http://" and .host removes "127.0.0.1" or given IP
final String href = ControllerLinkBuilder  
.linkTo(ControllerLinkBuilder.methodOn(LivetickerEventRestResource.class)  
.pushEventInDirection(dto.getId(), language, direction)).toUriComponentsBuilder()  
.scheme(null).host(null).toUriString();  

final Link link = new Link(href, rel);