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