{ }
GET
REST API · HATEOAS · Hypermedia · API Design
HATEOAS: Pragmatisches REST
und wann Hypermedia wirklich Sinn ergibt

HATEOAS ist das Prinzip, das REST von einem einfachen HTTP-Datentransport trennt – und gleichzeitig das meistdiskutierte und seltenst umgesetzte REST-Constraint. Dieser Artikel erklärt, was Hypermedia wirklich bedeutet, welche Formate sich bewährt haben und wann der Pragmatismus über die Reinheit geht.

12 Min. Lesezeit HAL · JSON:API · Richardson Maturity Model · REST Level 3 HTTP · REST · API Design

1. Was HATEOAS wirklich bedeutet

HATEOAS steht für Hypermedia as the Engine of Application State und ist eines der sechs Constraints, die Roy Fielding in seiner Dissertation 2000 für REST definiert hat. Der Kern des Prinzips ist einfach: Ein API-Client sollte niemals URLs kennen müssen, um mit einer API zu interagieren. Stattdessen enthält jede API-Antwort Links auf die nächsten möglichen Aktionen – ähnlich wie ein Webbrowser Seiten navigiert, ohne zuvor die URLs aller Links kennen zu müssen.

In der Praxis bedeutet das: Wenn ein Client einen Artikel abruft, enthält die Antwort nicht nur die Artikeldaten, sondern auch Links wie self (die URL des Artikels selbst), edit (die URL zum Bearbeiten), delete und author. Der Client entscheidet anhand dieser Links, welche Aktion als nächstes ausgeführt wird – ohne im Code eine einzige URL außer dem API-Einstiegspunkt fest verdrahtet zu haben. Dieses Prinzip macht APIs theoretisch versionierungsunabhängig: Wenn der Server die URLs ändert, folgen alle Clients einfach den neuen Links.

Warum wird HATEOAS so selten vollständig umgesetzt? Weil es einen erheblichen Aufwand auf Client- und Serverseite bedeutet, einen echten Mehrwert aber nur in bestimmten Szenarien bietet. Die meisten APIs bedienen einen bekannten, eng gekoppelten Client. Für diesen Fall ist vollständiges HATEOAS oft Over-Engineering – aber ein Verständnis des Prinzips hilft trotzdem dabei, bessere API-Designs zu entwickeln.

2. Das Richardson Maturity Model – Level 0 bis 3

Leonard Richardson hat 2008 ein Reifegradmodell für REST-APIs beschrieben, das vier Stufen unterscheidet. Level 0 ist der RPC-über-HTTP-Ansatz: Eine einzige URL, alle Anfragen per POST, das Protokoll ist ein selbst definiertes XML- oder JSON-Format. SOAP-Webservices und viele ältere JSON-RPC-APIs fallen in diese Kategorie. HTTP ist hier nur ein Transportprotokoll, keine semantische Grundlage.

Level 1 führt Ressourcen ein: Statt einer einzigen URL gibt es separate URLs für jeden Ressourcentyp (/orders, /customers, /products). Level 2 nutzt HTTP-Verben korrekt: GET für Lesezugriffe, POST für Erstellung, PUT/PATCH für Aktualisierung, DELETE für Löschung. HTTP-Statuscodes werden semantisch korrekt eingesetzt: 200, 201, 204, 404, 409, 422. Die meisten produktiven REST-APIs, die diesen Namen verdienen, befinden sich auf Level 2.

Level 3 ist HATEOAS: Jede Antwort enthält Hypermedia-Links auf die nächsten möglichen Aktionen. Der API-Client braucht nur den Einstiegspunkt zu kennen und navigiert von dort ausgehend durch alle Zustände. Das Modell ist eine nützliche Einordnung, kein Qualitätsurteil: Eine Level-2-API kann exzellent designed sein, eine Level-3-API schlecht. Das Reifegradmodell beschreibt Eigenschaften, nicht Güte.


// Level 2: Plain REST — client muss /orders/{id}/cancel kennen
{
  "id": 42,
  "status": "pending",
  "total": 129.90,
  "customerId": 7
}

// Level 3: HATEOAS — client folgt nur dem Link
{
  "id": 42,
  "status": "pending",
  "total": 129.90,
  "_links": {
    "self":   { "href": "/orders/42" },
    "cancel": { "href": "/orders/42/cancel", "method": "POST" },
    "pay":    { "href": "/orders/42/payment", "method": "POST" },
    "customer": { "href": "/customers/7" }
  }
}

3. HAL: Hypertext Application Language in der Praxis

HAL (Hypertext Application Language) ist das bekannteste Hypermedia-Format für JSON-APIs. Es definiert zwei reservierte Felder: _links für Links zu verwandten Ressourcen und Aktionen, sowie _embedded für eingebettete Ressourcen, die vollständig in die Antwort eingebettet sind, um Roundtrips zu vermeiden. HAL hat den Media-Type application/hal+json und ist als Internet-Draft bei der IETF spezifiziert, auch wenn der Draft niemals zum RFC wurde.

Die Stärke von HAL liegt in seiner Einfachheit. Ein _links-Objekt enthält benannte Link-Relationen als Schlüssel, wobei jede Relation entweder ein Link-Objekt mit href oder ein Array von Link-Objekten ist. Optionale Felder wie title, type (Media-Type der verlinkten Ressource) und templated (für URI-Templates wie /orders{?page,size}) ergänzen das Basisformat. Das _embedded-Feld erlaubt es, eine Liste von Bestellungen direkt in die Antwort einzubetten, statt pro Bestellung einen zusätzlichen GET-Request zu erzwingen.


// HAL-Response: Bestellungsliste mit eingebetteten Ressourcen
{
  "_links": {
    "self":  { "href": "/orders?page=1&size=10" },
    "next":  { "href": "/orders?page=2&size=10" },
    "first": { "href": "/orders?page=1&size=10" },
    "last":  { "href": "/orders?page=5&size=10" },
    "create": { "href": "/orders", "method": "POST", "title": "Neue Bestellung anlegen" }
  },
  "totalCount": 47,
  "page": 1,
  "size": 10,
  "_embedded": {
    "orders": [
      {
        "id": 42,
        "status": "pending",
        "total": 129.90,
        "_links": {
          "self":   { "href": "/orders/42" },
          "cancel": { "href": "/orders/42/cancel", "method": "POST" },
          "customer": { "href": "/customers/7" }
        }
      }
    ]
  }
}

4. JSON:API als Hypermedia-Alternative

JSON:API (jsonapi.org) ist eine vollständige Spezifikation für JSON-basierte APIs, die über einfache Hypermedia-Links hinausgeht. JSON:API definiert ein standardisiertes Format für Ressourcen, Beziehungen, Fehler, Paginierung und Links. Der Media-Type ist application/vnd.api+json. Jede Ressource hat eine eindeutige id und einen type, Attribute werden in einem attributes-Objekt gebündelt, Beziehungen in einem relationships-Objekt.

JSON:API enthält standardisierte Link-Felder auf Dokument- und Ressource-Ebene. Das Dokument kann links.self, links.first, links.prev, links.next und links.last für Paginierung enthalten. Ressourcen können individuelle Links auf sich selbst und verwandte Ressourcen enthalten. Der Vorteil gegenüber HAL: JSON:API ist deutlich umfangreicher spezifiziert, was zu mehr Interoperabilität zwischen Client-Bibliotheken führt. Der Nachteil: Das Format ist geschwätziger und erfordert mehr Aufwand zum Verstehen.

Die Wahl zwischen HAL und JSON:API hängt meist von der Client-Landschaft ab. Wenn mehrere unabhängige Clients die API konsumieren und Client-Bibliotheken genutzt werden sollen, ist JSON:API mit seiner breiteren Ökosystem-Unterstützung attraktiver. Für interne APIs mit einem bekannten Client ist HAL durch seine Einfachheit oft die bessere Wahl.

Das Herzstück von HATEOAS ist nicht das Format, sondern die Semantik der Link-Relationen. Der Schlüssel in einem _links-Objekt – zum Beispiel self, next, author oder cancel – ist eine Link-Relation (kurz: rel). Die IANA pflegt ein offizielles Register standardisierter Link-Relationen: self für die kanonische URL der Ressource, next und prev für Paginierung, alternate für alternative Repräsentationen, edit für den Bearbeitungs-Endpunkt.

Für anwendungsspezifische Relationen, die nicht im IANA-Register stehen, gibt es zwei Ansätze. Der RFC-konforme Weg ist eine absolute URI als Relation: "https://api.mironsoft.de/rels/cancel-order". In der Praxis werden meist kurze, selbsterklärende Bezeichner wie cancel, approve oder ship verwendet und in der API-Dokumentation beschrieben. Das ist pragmatischer, aber weniger interoperabel. Wer HATEOAS konsequent umsetzt, dokumentiert alle Link-Relationen in einem API-Profil oder verweist auf IANA-registrierte Relationen wo immer möglich.

6. Client-getriebene Navigation statt hartcodierter URLs

Das eigentliche Versprechen von HATEOAS ist, dass der API-Client keine URLs außer dem Einstiegspunkt kennen muss. In der Praxis bedeutet das, dass der Client beim Start einen Request gegen den API-Root (GET /api/) schickt und aus der Antwort die URLs für alle weiterführenden Aktionen extrahiert. Dieser Einstiegspunkt ist der einzige Vertrag zwischen Client und Server – alle anderen URLs können sich ändern, ohne den Client zu brechen.

Wie sieht das konkret aus? Ein Bestellprozess-Client ruft GET /api/ ab, findet darin _links.orders.href und führt daraufhin GET /orders aus. In der Antwort findet er _links.create für neue Bestellungen. Nach dem Erstellen einer Bestellung enthält die 201-Antwort _links.pay und _links.cancel. Der Client weiss nie, wie /orders/42/payment aufgebaut ist – er folgt einfach dem Link. Dieses Muster ist in Webbrowsern seit Jahrzehnten Standard; für API-Clients erfordert es ein Umdenken in der Architektur.


# HATEOAS-Navigation: nur Einstiegspunkt ist hartcodiert
BASE="https://api.mironsoft.de/api"

# Step 1: Einstiegspunkt abrufen
ROOT=$(curl -s -H "Accept: application/hal+json" "$BASE/")
ORDERS_URL=$(echo "$ROOT" | jq -r '._links.orders.href')

# Step 2: Bestellungen laden (URL aus Link-Relation, nicht hartcodiert)
ORDERS=$(curl -s -H "Accept: application/hal+json" "$ORDERS_URL")
CREATE_URL=$(echo "$ORDERS" | jq -r '._links.create.href')

# Step 3: Neue Bestellung anlegen
NEW_ORDER=$(curl -s -X POST "$CREATE_URL" \
  -H "Content-Type: application/json" \
  -H "Accept: application/hal+json" \
  -d '{"productId": 15, "quantity": 2}')

# Step 4: Zahlungs-URL aus der Antwort extrahieren — keine hartcodierte URL
PAY_URL=$(echo "$NEW_ORDER" | jq -r '._links.pay.href')
curl -s -X POST "$PAY_URL" -H "Content-Type: application/json" \
  -d '{"method": "credit_card", "token": "tok_xyz"}'

7. Wann HATEOAS wirklich sinnvoll ist

HATEOAS entfaltet seinen Wert in ganz bestimmten Szenarien. Das erste ist die öffentliche API mit unbekannten Clients: Wenn eine API von Drittentwicklern konsumiert wird, die ihre Clients unabhängig weiterentwickeln, reduzieren Hypermedia-Links die Kopplung an konkrete URL-Strukturen erheblich. Wenn der Server URL-Muster ändert – etwa beim Einführen von API-Versionierung oder beim Umstrukturieren von Ressourcenhierarchien – bleiben Clients, die HATEOAS konsequent umgesetzt haben, funktionsfähig.

Das zweite Szenario sind zustandsabhängige Workflows, bei denen bestimmte Aktionen nur in bestimmten Zuständen verfügbar sind. Eine Bestellung kann nur bezahlt werden, wenn sie im Status pending ist. Nur storniert werden, wenn sie noch nicht versandt wurde. In einer HATEOAS-API signalisiert das Fehlen des entsprechenden Links direkt, dass die Aktion nicht verfügbar ist – kein Client-seitiges State-Management, keine hartcodierten Geschäftsregeln im Frontend. Der Link cancel erscheint nur, wenn der Server die Stornierung erlaubt.

HATEOAS ist hingegen nicht sinnvoll bei eng gekoppelten internen APIs, die von einem einzigen bekannten Client konsumiert werden. Wenn Frontend und Backend im selben Repository liegen und gemeinsam deployed werden, bringt HATEOAS keinen Entkopplungsvorteil, aber erheblichen Implementierungsaufwand. Für Mobile-Apps, die sich selten aktualisieren und über App-Store-Prozesse gebunden sind, kann HATEOAS die Versionierungsprobleme lösen – aber nur, wenn das Client-Framework wirklich link-getrieben navigiert.

8. Der pragmatische Mittelweg

Die pragmatische Empfehlung für die meisten Projekte: Partial Hypermedia. Das bedeutet, gezielt dort Links einzubauen, wo sie echten Mehrwert bieten, ohne HATEOAS vollständig zu implementieren. Konkret: Ein self-Link in jeder Ressource ist immer sinnvoll und kostet fast nichts. Paginierungs-Links (next, prev, first, last) sind ein universell nützliches Muster, das die Client-Implementierung vereinfacht. Zustandsabhängige Aktions-Links für Workflows sind dort sinnvoll, wo sich erlaubte Aktionen je nach Ressourcenzustand ändern.

Was Partial Hypermedia nicht bedeutet: URLs für alle möglichen Ressourcen mitzugeben. Ein Benutzer-Objekt braucht keinen Link auf alle seine Bestellungen, wenn der Client diese sowieso nie dynamisch navigiert, sondern immer direkt /orders?userId=7 aufruft. Der Mittelweg erfordert bewusste Entscheidungen: Wo navigiert der Client wirklich dynamisch? Wo sind die Links nur formale Vollständigkeit ohne praktischen Nutzen? Diese Abwägung ist wichtiger als das dogmatische Einhalten von Level 3.

9. HATEOAS-Formate im Vergleich

Kriterium Plain JSON HAL JSON:API
Einstiegshürde Sehr niedrig Niedrig Mittel bis hoch
Standardisierung Keine Internet-Draft (IETF) Vollständige Spezifikation
Client-Bibliotheken Keine Wenige Umfangreiches Ökosystem
Paginierung Selbst definieren Links-Konvention Standardisiert
Response-Größe Klein Mittel Groß
Zustandsabhängige Links Nicht vorgesehen Möglich Möglich

Die Wahl des Formats ist weniger wichtig als die Konsequenz bei der Umsetzung. Eine inkonsequente HATEOAS-Implementierung, die nur bei manchen Endpunkten Links mitliefert, bietet weder die Vorteile des Partial-Hypermedia-Ansatzes noch die volle Entkopplung. Wer sich für HAL oder JSON:API entscheidet, sollte das über alle Endpunkte konsistent durchziehen und die Link-Relationen in der API-Dokumentation klar beschreiben.

Mironsoft

REST API Design, Hypermedia-Architektur und API-Dokumentation

REST-APIs, die wirklich RESTful sind?

Wir entwerfen und implementieren REST-APIs, die pragmatisch HATEOAS nutzen – mit klaren Link-Relationen, konsistenten Hypermedia-Mustern und einer API-Dokumentation, die Clients wirklich hilft.

API Design Review

Analyse bestehender APIs auf REST-Konformität, Hypermedia-Potenzial und Konsistenz

HAL / JSON:API

Implementierung von Hypermedia-Links in bestehende REST-APIs – schrittweise und abwärtskompatibel

OpenAPI-Dokumentation

Vollständige API-Spezifikation mit Link-Relationen, Zustandsdiagrammen und Beispiel-Flows

10. Zusammenfassung

HATEOAS ist kein Selbstzweck, sondern ein Werkzeug für die richtige Situation. Das Richardson Maturity Model hilft bei der Einordnung, ist aber kein Zertifizierungsprogramm. Level 2 – korrekte HTTP-Verben, Statuscodes und ressourcenorientierte URLs – ist die solide Basis, auf der die allermeisten produktiven APIs stehen sollten. Level 3 mit vollständigem HATEOAS lohnt sich, wenn echte Entkopplungsvorteile entstehen: bei öffentlichen APIs mit unabhängigen Clients, bei zustandsabhängigen Workflows und bei APIs, die über lange Zeiträume ohne Client-Breaks versioniert werden müssen.

Der pragmatische Mittelweg – Paginierungs-Links, self-Links und zustandsabhängige Aktions-Links – bietet den größten Nutzen pro Implementierungsaufwand. HAL ist für die meisten Projekte das richtige Format: einfach genug, um es ohne spezielle Bibliotheken zu konsumieren, und ausreichend standardisiert, um interoperabel zu sein. JSON:API ist die bessere Wahl, wenn ein starkes Ökosystem mit Client-Bibliotheken genutzt werden soll und das umfangreichere Format kein Problem ist.

HATEOAS und Hypermedia — Das Wichtigste auf einen Blick

Richardson Maturity Model

Level 0 (RPC) → Level 1 (Ressourcen) → Level 2 (HTTP-Verben) → Level 3 (HATEOAS). Die meisten APIs sollten auf Level 2 abzielen, Level 3 nur wenn echte Entkopplung nötig ist.

Link-Relationen

IANA-standardisierte Relationen wie self, next, prev nutzen wo möglich. Eigene Relationen in der API-Dokumentation beschreiben. Konsistenz wichtiger als Vollständigkeit.

HAL vs. JSON:API

HAL ist einfacher und für interne APIs gut geeignet. JSON:API ist vollständiger spezifiziert und hat mehr Client-Bibliotheken – besser für öffentliche APIs mit breiter Client-Landschaft.

Pragmatischer Einstieg

Mit self-Links und Paginierungs-Links beginnen. Zustandsabhängige Aktions-Links für Workflows hinzufügen. Vollständige HATEOAS-Navigation nur wo echte Entkopplung nötig ist.

11. FAQ: HATEOAS und Hypermedia in REST-APIs

1Was ist HATEOAS?
Hypermedia as the Engine of Application State – API-Antworten enthalten Links auf nächste Aktionen. Client kennt nur den Einstiegspunkt, navigiert dynamisch über Links.
2Richardson Maturity Model?
Level 0 (RPC) → Level 1 (Ressourcen) → Level 2 (HTTP-Verben) → Level 3 (HATEOAS). Beschreibt Eigenschaften, kein Qualitätsurteil. Level 2 ist die solide Basis für die meisten APIs.
3HAL vs. JSON:API?
HAL einfacher, als IETF-Draft spezifiziert. JSON:API vollständiger, mehr Client-Bibliotheken. HAL für interne APIs, JSON:API für öffentliche APIs mit breitem Ökosystem.
4Wann HATEOAS einsetzen?
Bei öffentlichen APIs mit unbekannten Clients und bei zustandsabhängigen Workflows. Nicht bei eng gekoppelten internen APIs mit einem einzigen bekannten Client.
5Was sind Link-Relationen?
Schlüssel in _links-Objekten (self, next, cancel etc.). IANA-standardisierte Relationen bevorzugen. Eigene Relationen in der API-Dokumentation beschreiben.
6Wie navigiert ein HATEOAS-Client?
Nur Einstiegspunkt ist bekannt. Aus jeder Antwort werden Links extrahiert. Keine weiteren URLs hartcodiert. URL-Änderungen am Server brechen keine Clients.
7Was ist Partial Hypermedia?
Pragmatischer Mittelweg: Self-Links, Paginierungs-Links und zustandsabhängige Aktions-Links – ohne vollständige HATEOAS-Navigation zu implementieren.
8Nicht verfügbare Aktionen signalisieren?
Durch Fehlen des Links. Kein cancel-Link = Stornierung nicht möglich. Client implementiert keine eigene State-Machine – Server kommuniziert Zustand über Links.
9Level 2 schlechter als Level 3?
Nein. Das Reifegradmodell beschreibt Eigenschaften. Eine exzellente Level-2-API ist besser als eine schlecht implementierte Level-3-API. HATEOAS nur wo sinnvoll.
10Was ist ein URI-Template in HAL?
Link mit templated: true nach RFC 6570, z.B. /orders{?page,size}. Client expandiert mit konkreten Werten. Nützlich für filterbare, suchbare Ressourcen.