Now I want to add HATEOAS to this REST api. Meaning that instead of just returning the data (let's say this is a reservation), it would also return links for cancelling the reservation and updating it.
So I think you have a misunderstanding of HATEOAS.
HATEOAS doesn't mean that you perform actions on a resource via hyperlinks to commands like cancelling or updating.
So if your URLs look something like this
reservation/343/cancel
reservation/343/update
you are not following HATEOAS.
Remember REST is REpresentational State Transfer. You change the current state of a resource (such as reservation/343
) by transfering an updated state of that resource from the client to the server. The URL stays the same.
And this fits neatly with CQRS, since in HTTP there is a read request (GET) and requests that change the state of the resource (PUT, DELETE). Your server can neatly handle these requests through different paths in your application.
To simply read current state of the reservation from the server the client just does a GET reservation/343
returning some representation such as
{
customer: 'customers/123',
status: 'live'
}
To cancel this reservation you could just ask the server to delete it (DELETE reservation/343
) or probably more commonly update it since most reservation systems want to keep a record of cancelled reservations
PUT reservation/343
{
customer: 'customers/123',
status: 'cancelled'
}
note here the client has changed the status field to cancelled
and asked the server to update its version via a PUT
.
The server will need some logic to figure out what has changed and do anything it needs to do because of this change (update a database, email a customer etc), but that is for the server to worry about. And most importantly all that logic for updating the server can be piped through your 'write' pipeline in the application.
You can tell easily what requests are going to potentially write to the system just be looking at the HTTP verb (GET vs PUT,DELETE etc). Maybe the client doesn't have authorisation to update the resource to cancelled? That check only has to be done when you get a PUT
request from the server, the GET
request can ignore it because with a GET
the client is not attempting to update any state of the resource.
This is all standard REST.
So what does HATEOS mean if it doesn't mean making command URLs for actions to carry out on the resource.
Well look at the representation of the reservation. Notice that the customer
field for the customer that booked the reservation isn't just an id. It is a hyperlink.
We could have just put an id there
{
customer: 123,
status: 'cancelled'
}
but then the client would have to know how to turn that id into a URL in order to navigate to the customer who made this reservation.
Instead when you use a link if the client wants to start at a reservation and then navigate to the customer that made the reservation it simply follows that hyper link to get to the customer. It doesn't have to know in advance how to construct that hyperlink from a customer id.
And, importantly, the server might change the URL scheme at some point, but the client won't care because it is just following the hyper link.
So say next week the server developers decide that the URL scheme needs and update. All of a sudden clients are getting this resource back
{
customer: 'europe/customers/123',
status: 'live'
}
The clients won't care. Yes the customer's URL has changed, but the client doesn't care because all it did was follow what ever URL was for that customer.
So HATEOAS simply says that any time you have another resource in the system represent it as a URL so that the client can navigate to it using hypertext links.