Skip to main content

HATEOAS

HATEOAS is a REST constraint stating that:

Clients interact with a REST API entirely through hypermedia provided dynamically by the server.

Clients do not hardcode URLs or workflows.

Core HATEOAS Concepts​

ConceptDescription
LinksURLs to related actions
RelRelationship meaning
State transitionsValid next actions
Hypermedia formatHAL, JSON:API, Siren, etc.

Example Without HATEOAS​

{
"id": 10,
"status": "pending"
}
  • Client doesn’t know what actions are allowed
  • Requires documentation to know next steps

Example With HATEOAS​

HTTP/1.1 200 OK
Content-Type: application/hal+json

{
"id": 10,
"status": "pending",
"_links": {
"self": {
"href": "/orders/10"
},
"cancel": {
"href": "/orders/10/cancel",
"method": "POST"
},
"pay": {
"href": "/orders/10/pay",
"method": "POST"
}
}
}
ElementPurpose
selfCanonical resource URL
cancelAllowed action
payValid state transition
methodHow to invoke action

State-Dependent Discoverability​

If order is already paid:

{
"id": 10,
"status": "paid",
"_links": {
"self": {
"href": "/orders/10"
},
"receipt": {
"href": "/orders/10/receipt"
}
}
}

Common HATEOAS Media Types​

Media TypeUsage
HALSimple hypermedia format
JSON:APIStructured, standardized
SirenComplex workflows
Collection+JSONCollections & navigation

Why HATEOAS Is Often Optional in Practice​

Reasons for Limited Adoption

  • Added complexity
  • Client tooling limitations
  • Mobile & SPA clients prefer known endpoints
  • Well-documented APIs reduce need

When HATEOAS Is Worth Using

  • Public APIs
  • Long-lived APIs
  • APIs requiring backward compatibility
  • Highly dynamic workflows