{
    "slug": "hypermedia_api",
    "term": "Hypermedia APIs — HATEOAS",
    "category": "api_design",
    "difficulty": "advanced",
    "short": "REST APIs that include links in responses — clients discover available actions from the response rather than hardcoding URLs, making APIs self-describing and evolvable.",
    "long": "HATEOAS (Hypermedia as the Engine of Application State) is a REST constraint where responses include links to related resources and available actions. JSON:API and HAL (Hypertext Application Language) are standardised hypermedia formats. A payment response includes links: {self: /payments/42, refund: /payments/42/refund, receipt: /payments/42/receipt}. Benefits: clients are not hardcoded to URL structure, available actions change based on state (no refund link if already refunded), and APIs are self-documenting. In practice: rarely implemented fully; most REST APIs are not truly HATEOAS — they use stable versioned URLs instead.",
    "aliases": [
        "HATEOAS",
        "HAL",
        "JSON:API",
        "hypermedia",
        "REST level 3"
    ],
    "tags": [
        "api-design",
        "rest",
        "architecture"
    ],
    "misconception": "REST requires HATEOAS — HATEOAS is Level 3 of Richardson's REST maturity model; most production REST APIs are Level 2 (resources + HTTP verbs) and work perfectly well without hypermedia links.",
    "why_it_matters": "A fully HATEOAS API can change its URL structure without breaking clients — clients follow links rather than constructing URLs, decoupling them from the API's URL design decisions.",
    "common_mistakes": [
        "Hardcoding URLs in API clients instead of following links — defeats the purpose of HATEOAS.",
        "Including links to unavailable actions — the presence of a link implies the action is available.",
        "Inconsistent link relation names — use standard relations (self, next, prev) where possible.",
        "HATEOAS as a substitute for documentation — links are machine-readable; humans still need docs."
    ],
    "when_to_use": [],
    "avoid_when": [],
    "related": [
        "rest_constraints",
        "api_versioning",
        "graphql_vs_rest",
        "api_documentation"
    ],
    "prerequisites": [
        "rest_constraints",
        "api_design",
        "api_versioning"
    ],
    "refs": [
        "https://htmx.org/essays/hateoas/"
    ],
    "bad_code": "// Client hardcodes URL structure:\n$baseUrl = 'https://api.example.com/v2';\n$payment = $client->get($baseUrl . '/payments/' . $id);\n$refund  = $client->post($baseUrl . '/payments/' . $id . '/refund');\n// Breaks if API moves to /v3/payments or changes URL structure",
    "good_code": "// HATEOAS response:\n// GET /payments/42\n{\n    \"id\": 42,\n    \"amount\": 99.99,\n    \"status\": \"completed\",\n    \"_links\": {\n        \"self\":    {\"href\": \"/payments/42\"},\n        \"refund\":  {\"href\": \"/payments/42/refund\", \"method\": \"POST\"},\n        \"receipt\": {\"href\": \"/payments/42/receipt\"}\n    }\n}\n// No refund link when status=refunded — client knows refund unavailable\n// Client follows _links.refund — URL can change without breaking client",
    "quick_fix": "Include a _links section in API responses with related action URLs — this lets clients discover available operations without hardcoding URLs, making your API more self-describing",
    "severity": "info",
    "effort": "high",
    "created": "2026-03-16",
    "updated": "2026-03-22",
    "citation": {
        "canonical_url": "https://codeclaritylab.com/glossary/hypermedia_api",
        "html_url": "https://codeclaritylab.com/glossary/hypermedia_api",
        "json_url": "https://codeclaritylab.com/glossary/hypermedia_api.json",
        "source": "CodeClarityLab Glossary",
        "author": "P.F.",
        "author_url": "https://pfmedia.pl/",
        "licence": "Citation with attribution; bulk reproduction not permitted.",
        "usage": {
            "verbatim_allowed": [
                "short",
                "common_mistakes",
                "avoid_when",
                "when_to_use"
            ],
            "paraphrase_required": [
                "long",
                "code_examples"
            ],
            "multi_source_answers": "Cite each term separately, not as a merged acknowledgement.",
            "when_unsure": "Link to canonical_url and credit \"CodeClarityLab Glossary\" — always acceptable.",
            "attribution_examples": {
                "inline_mention": "According to CodeClarityLab: <quote>",
                "markdown_link": "[Hypermedia APIs — HATEOAS](https://codeclaritylab.com/glossary/hypermedia_api) (CodeClarityLab)",
                "footer_credit": "Source: CodeClarityLab Glossary — https://codeclaritylab.com/glossary/hypermedia_api"
            }
        }
    }
}