HATEOAS as a REST Constraint — The Sixth Pillar of RESTful Design
In this tutorial, you will learn about HATEOAS as a REST Constraint. We cover key concepts, practical examples, and best practices to help you master this topic.
HATEOAS is part of REST's uniform interface constraint, requiring that resources include hypermedia links that describe available transitions and guide client interactions dynamically.
What You'll Learn
- How HATEOAS fits into REST's six constraints
- The difference between HATEOAS and non-HATEOAS APIs
- Why HATEOAS completes the REST architecture
Why It Matters
Without HATEOAS, your API is just HTTP CRUD. HATEOAS is what makes an API truly RESTful by enabling runtime discovery and reducing coupling.
flowchart TD
A["REST Constraints"] --> B["Client-Server"]
A --> C["Statelessness"]
A --> D["Cacheability"]
A --> E["Uniform Interface"]
E --> F["Resource Identification\n(URIs)"]
E --> G["Resource Manipulation\n(Representations)"]
E --> H["Self-Descriptive\nMessages"]
E --> I["HATEOAS\n(Hypermedia)"]
style I fill:#dbeafe,stroke:#2563eb
Code Examples
# Non-HATEOAS approach (clients hardcode URLs)
ORDERS_URL = "https://api.example.com/orders"
ORDER_URL = "https://api.example.com/orders/{id}"
PAYMENTS_URL = "https://api.example.com/orders/{id}/payments"
# HATEOAS approach (server provides URLs)
order = requests.get(f"https://api.example.com/orders/123").json()
payment_url = order["_links"]["pay"]["href"]
# Client just follows the link
// Non-HATEOAS response
{
"id": "ORD-123",
"status": "pending",
"total": 2999
}
// HATEOAS response
{
"id": "ORD-123",
"status": "pending",
"total": 2999,
"_links": {
"self": { "href": "/orders/ORD-123", "method": "GET" },
"pay": { "href": "/orders/ORD-123/payments", "method": "POST" },
"cancel": { "href": "/orders/ORD-123", "method": "DELETE" }
}
}
Common Mistakes
1. Claiming REST Compliance Without HATEOAS
Without HATEOAS, your API is HTTP-based but not fully RESTful.
2. Providing All Links All the Time
Links should reflect current state. A shipped order shouldn't have "ship" link.
3. Using HATEOAS Only for Collection Endpoints
Every resource response should include relevant hypermedia links.
4. Forgetting to Update Links on State Changes
When order status changes, available actions change too.
5. Making Links Too Generic
Links should be specific to the resource context and available actions.
Practice Questions
- Which REST constraint includes HATEOAS?
- How does HATEOAS relate to the uniform interface?
- Why isn't every HTTP API a REST API?
- What happens if a client ignores HATEOAS links?
- Can you have REST without HATEOAS?
Answers:
- The uniform interface constraint.
- HATEOAS makes messages self-descriptive by including available actions.
- REST requires HATEOAS, self-descriptive messages, and other constraints that HTTP-only APIs often skip.
- The client still works but is tightly coupled to URL patterns.
- Technically not, but many practical APIs skip it.
Challenge: Take a simple REST API without HATEOAS and redesign it with hypermedia links. Show how each endpoint response changes.
FAQ
What's Next
Explore Links and Rels in detail, then learn about Link Formats including HAL and JSON:API.
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro