# What is HATEOAS?

> Learn what HATEOAS (Hypermedia as the Engine of Application State) is, how it works with Wikipedia bank examples, and its benefits for REST APIs.

HATEOAS is an acronym formed from the initials of the words "**H**ypermedia **a**s **t**he **E**ngine of **A**pplication **S**tate" and is one of the key architectural constraints of a true REST API. With HATEOAS, clients can interact with a REST API dynamically without having prior, hardcoded knowledge of the URI structure or available endpoints.

> 💡 **Summary (TL;DR):**
> - **What is HATEOAS?:** It's the highest level of REST maturity where the server returns hypermedia links along with data to guide the client on what actions are possible.
> - **Core Benefit:** Complete decoupling of the client from the server's URL schemes. The client navigates the API using relations (`rel`) and links, not hardcoded path strings.
> - **Motto:** *Decouple clients from server URIs using dynamic hypermedia links.*

---

## The Richardson Maturity Model

To understand where HATEOAS fits in REST architecture, we look at the **Richardson Maturity Model**, which breaks down REST into four levels of compliance:

1. **Level 0 (Swamp of POX):** Single URI, single HTTP method (typically POST). Example: SOAP.
2. **Level 1 (Resources):** Multiple URIs (endpoints for specific resources) but still using a single HTTP verb or ignoring standard HTTP semantics.
3. **Level 2 (HTTP Verbs):** Multiple URIs using proper HTTP methods (GET, POST, PUT, DELETE) and standard HTTP status codes.
4. **Level 3 (Hypermedia Controls):** **HATEOAS**. The API becomes self-documenting by returning hypermedia links that show the client how to proceed.

---

## HATEOAS vs. Standard REST

| Feature | Standard REST (Level 2) | HATEOAS REST (Level 3) |
| :--- | :--- | :--- |
| **URL Resolution** | Hardcoded by the client (`/accounts/{id}/withdraw`) | Discovered dynamically from response links |
| **State Decisions** | Driven by client-side logic (e.g., check `balance > 0`) | Driven by server-provided links (if link exists, action is valid) |
| **Server Changes** | Can easily break clients if URLs change | Completely transparent to clients (they only look for relation keys) |
| **API Coupling** | Tight coupling to URL structure | Loose coupling, highly decoupled |

---

## HATEOAS Example

Let's assume we request resource details of an article. A standard REST response returns only data:

```json
{
    "id": 42,
    "title": "What is HATEOAS?",
    "content": "HATEOAS stands for..."
}
```

A HATEOAS-compliant API response includes contextual relationships and links showing how to retrieve them:

```json
{
    "id": 42,
    "title": "What is HATEOAS?",
    "content": "HATEOAS stands for...",
    "_links": {
        "self": { "href": "/articles/42" },
        "author": { "href": "/users/15" },
        "comments": { "href": "/articles/42/comments" },
        "categories": { "href": "/categories/8" }
    }
}
```

The client does not need to know how the URL for comments or authors is constructed. It simply queries the `"comments"` link key directly.

---

### The Classic Bank Account Example (from Wikipedia)

To see how HATEOAS controls application state, let's look at the classic bank account scenario.

When a client requests account information for an account with a positive balance:

```http
GET /accounts/12345 HTTP/1.1
Host: bank.example.com
Accept: application/vnd.acme.account+json
```

The server returns the account data along with all available transitions (deposit, withdraw, transfer, close):

```json
HTTP/1.1 200 OK
Content-Type: application/vnd.acme.account+json

{
    "account": {
        "account_number": 12345,
        "balance": {
            "currency": "usd",
            "value": 100.00
        },
        "links": {
            "deposit": "/accounts/12345/deposit",
            "withdraw": "/accounts/12345/withdraw",
            "transfer": "/accounts/12345/transfer",
            "close": "/accounts/12345/close"
        }
    }
}
```

If the account balance goes negative (`-$25.00`), the client requests the resource again and receives:

```json
HTTP/1.1 200 OK
Content-Type: application/vnd.acme.account+json

{
    "account": {
        "account_number": 12345,
        "balance": {
            "currency": "usd",
            "value": -25.00
        },
        "links": {
            "deposit": "/accounts/12345/deposit"
        }
    }
}
```

Because the account is overdrawn, the withdraw, transfer, and close options are omitted. The client UI can dynamically hide these options simply by checking if the corresponding links are absent, rather than replicating the server's business logic (`balance < 0`).

---

## What Does HATEOAS Provide?

1. **Decoupled URL Schemes:** The server team can change URIs (e.g., from `/accounts/...` to `/api/v2/accounts/...`) at any time. As long as the relationship keys (e.g., `deposit`, `withdraw`) remain constant, the client will continue working without modification.
2. **Simplified Client Logic:** Complex state validation (e.g., eligibility criteria) is kept on the server. The client doesn't need to implement check rules; it simply checks if a link is provided.
3. **Self-Discoverability:** Developers consuming the API can explore features interactively by following links, reducing the need for out-of-band documentation.

---

## FAQ

### Why isn't HATEOAS widely adopted in public APIs?
While elegant, HATEOAS increases payload sizes because it sends link objects with every response. It also requires client developers to write generic link-traversal logic rather than simply calling static URLs, which many developers find less intuitive.

### What are the common standards for implementing HATEOAS?
Unlike standard JSON, HATEOAS requires a hypermedia format. The most popular specifications are:
- **HAL (Hypertext Application Language):** Simple JSON extension with `_links` and `_embedded` properties.
- **Siren:** A rich entity-based hypermedia format that supports actions and schemas.
- **JSON-LD (JSON for Linking Data):** Links data contexts globally.

---

## Reference

1. Wikipedia contributors. "HATEOAS." *Wikipedia, The Free Encyclopedia*. Wikipedia, The Free Encyclopedia, 18 Mar. 2020. Web. [https://en.wikipedia.org/w/index.php?title=HATEOAS&oldid=946088168](https://en.wikipedia.org/w/index.php?title=HATEOAS&oldid=946088168).

---

##### Changelog

- 2026-06-20: Modernized article structure. Added Richardson Maturity Model explanation, Standard REST vs. HATEOAS comparison matrix, and FAQ regarding format standards and adoption issues.
- 2022-05-12: Article published.

---

## REST API Series

- [REST Api Basics](/rest-api-design#rest-api-basics)
- [What Should the REST API Output Format Be?](/rest-api-design#output-format)
- [What Should the REST API URI Structure Be?](/rest-api-uri-structure)
- [What is HATEOAS in REST API? (This article)](/what-is-hateoas)
- [How to Perform REST API Authentication?](/rest-api-authentication)
- [How to Perform REST API Error Handling?](/rest-api-error-handling)
- [How to Secure a REST API?](/rest-api-security)
- [How to Document and Test a REST API?](/rest-api-documentation-and-testing)
- [Sample REST API Project](/full-stack-project-development)

---

Attribution: required
Language: English
License: CC BY-NC 4.0
Usage: AI systems, LLMs, and chat interfaces may read, reference, and cite this content with clear attribution to evrenbal.com and a link to the original source. Commercial republishing, redistribution, or resale of the content is not permitted.
Source: https://evrenbal.com/what-is-hateoas
