HAL itself doesn’t include any format to display these affordances. If you have multiple links at the same URI in a given resource, HAL will simply show one link. Thankfully, the popularity of HAL in the world of REST has caused derivative specs to start being developed.

HAL-FORMS is a HAL extension that looks like any other HAL document with one additional field: _templates. This field allows displaying methods as well as properties.

Assuming the single item Resource<Employee> code up above connected a Spring MVC @GetMapping endpoint to a @PutMapping endpoint (and you had some employee data loaded into the database), Spring HATEOAS will generate HAL-FORMS hypermedia like this:

{ "id" : 1, "firstName" : "Frodo", "lastName" : "Baggins", "role" : "ring bearer", "_links" : { "self" : { "href" : "http://localhost:8080/employees/1" }, "employees" : { "href" : "http://localhost:8080/employees" } }, "_templates" : { "default" : { "title" : null, "method" : "put", "contentType" : "", "properties" : [ { "name" : "firstName", "required" : true }, { "name" : "id", "required" : true }, { "name" : "lastName", "required" : true }, { "name" : "role", "required" : true } ] }, "deleteEmployee" : { "title" : null, "method" : "delete", "contentType" : "", "properties" : [ ] } } }

When you do a GET /employees/1 , this HAL-FORMS document shows both data and links. But more importantly, it gives you a template for editing the resource (the default template). Since HAL-FORMS presumes you are working against the self link, you could do a PUT /employees/1 to make an update. And the properties it would be looking for include firstName , id , lastName , and role .

These hypermedia controls also indicate that you can issue a DELETE /employees/1 request (the deleteEmployee template). No properties involved.

At first glance, this may not appear very impressive since you could already read that in the data shown at the top. But this format grants you the ability to write a little frontend JavaScript, and transform that template into:

<form method="put" action="http://localhost:8080/employees/1"> <input type="text" id="firstName" name="firstName"/> <input type="text" id="id" name="id" /> <input type="text" id="lastName" name="lastName" /> <input type="text" id="role" name="role" /> <input type="submit" value="Submit" /> </form>

By mixing the self link with the listed properties, you can create a real HTML form, purely driven by the hypermedia. This completes the synergy of REST by letting the server push domain-specific details straight to the user of the site. There is no need to code this bit of domain knowledge into the client, hence reducing coupling. Instead, just convert the hypermedia’s template into a form. Then, as domain updates occur on the server side, the client can adapt with little friction.

In short, HAL-FORMS is designed to show other actions available against the same URI.

Reading all this, did you find yourself asking the question, "why not just push an HTML form out instead of some JSON?" That is a fair question.