HATEOAS and Hypermedia APIs — Core Concepts
What HATEOAS actually means
HATEOAS stands for Hypermedia As The Engine Of Application State. It’s the constraint that makes REST truly RESTful according to Roy Fielding’s original dissertation. The idea: API responses should include hyperlinks that tell the client what actions are available next, just as a web page includes links to other pages.
Most APIs that call themselves “REST” aren’t actually RESTful by this definition. They’re what Martin Fowler calls Richardson Maturity Model Level 2 — they use HTTP methods and resources correctly, but clients still depend on hardcoded URL patterns from documentation.
How it works in practice
A non-HATEOAS response for a bank account:
{
"id": 42,
"balance": 1500.00,
"status": "active"
}
The client has to know that withdrawals go to /accounts/42/withdraw and transfers to /accounts/42/transfer. If the URL structure changes, every client breaks.
A HATEOAS response for the same account:
{
"id": 42,
"balance": 1500.00,
"status": "active",
"links": [
{"rel": "self", "href": "/accounts/42", "method": "GET"},
{"rel": "deposit", "href": "/accounts/42/deposit", "method": "POST"},
{"rel": "withdraw", "href": "/accounts/42/withdraw", "method": "POST"},
{"rel": "transfer", "href": "/accounts/42/transfer", "method": "POST"},
{"rel": "close", "href": "/accounts/42/close", "method": "DELETE"}
]
}
If the account is overdrawn, the server can omit the withdraw link entirely. The client doesn’t need conditional logic — it checks which links are present and enables/disables UI buttons accordingly.
Standard hypermedia formats
Several standards exist for structuring hypermedia responses:
- HAL (Hypertext Application Language): Uses
_linksand_embeddedkeys. Simple and widely adopted. Used by Amazon’s AppStream API. - JSON:API: Opinionated format with
relationships,included, andlinks. Enforces consistency across an entire API. Used by Ember.js ecosystem. - Siren: Adds
actionswith field definitions (like HTML forms). More expressive but more verbose. - Collection+JSON: Designed for managing collections of items with templates for creating new ones.
HAL is the most common choice for Python APIs due to its simplicity.
The real benefits
Evolvability. The server can change URL structures, add new actions, or remove deprecated ones without breaking clients. This is powerful when you have mobile apps that can’t be forced-updated.
Self-documenting flows. A client can discover available actions by following links rather than reading documentation. This reduces integration errors.
Server-driven workflow. Business logic stays on the server. An e-commerce checkout can add or remove steps (add a verification step for high-value orders) without client changes.
Common misconception
“HATEOAS means I don’t need API documentation.” Wrong. Clients still need to understand what each rel type means (what does withdraw expect as a body?). Documentation shifts from “here are all the URLs” to “here are all the relation types and their semantics.” The benefit isn’t eliminating docs — it’s eliminating hardcoded URL dependencies.
When it’s worth the effort
HATEOAS adds complexity. It’s worth it when:
- You have many clients you can’t update simultaneously (mobile apps, third-party integrations)
- Your API has complex workflows with conditional paths
- You need to evolve URLs without breaking consumers
It’s probably not worth it for internal APIs consumed by a single frontend team that deploys alongside the backend.
One thing to remember: HATEOAS decouples clients from URL structures — the server tells clients what they can do next instead of expecting them to already know.
See Also
- Python Aiohttp Client Understand Aiohttp Client through a practical analogy so your Python decisions become faster and clearer.
- Python Api Client Design Why building your own API client in Python is like creating a TV remote that only has the buttons you actually need.
- Python Api Documentation Swagger Swagger turns your Python API into an interactive playground where anyone can click buttons to try it out — no coding required.
- Python Api Mocking Responses Why testing with fake API responses is like rehearsing a play with stand-ins before the real actors show up.
- Python Api Pagination Clients Why APIs send data in pages, and how Python handles it — like reading a book one chapter at a time instead of swallowing the whole thing.