Sollten REST-APIs HATEOAS-Hypermedia-Links implementieren?
TL;DR
HATEOAS (Hypermedia as the Engine of Application State) ist theoretisch elegant, aber praktisch komplex. Die meisten APIs verzichten auf vollständiges HATEOAS und verwenden selektive Hypermedia-Links für Paginierung, verwandte Ressourcen und Aktionen. Die Modern PetstoreAPI implementiert praktische Hypermedia-Links, ohne Clients zu zwingen, vollständig hypermedia-gesteuert zu sein.
Einleitung
Sie lesen über das Design von REST-APIs. Dabei stoßen Sie auf HATEOAS (Hypermedia as the Engine of Application State). Die Erklärung besagt: „Clients sollten alle Aktionen über Hypermedia-Links entdecken, nicht über festcodierte URLs.“
Sie denken: „Das klingt kompliziert. Macht das wirklich jemand?“
Die Antwort: nicht wirklich. HATEOAS ist die am häufigsten ausgelassene REST-Einschränkung. Roy Fielding (der REST erfunden hat) hält es für wesentlich. Die meisten API-Designer halten es für unpraktisch. Das Ergebnis: Die meisten „REST“-APIs sind nach Fieldings Definition nicht wirklich RESTful.
Modern PetstoreAPI verfolgt einen pragmatischen Ansatz: Hypermedia-Links werden dort eingesetzt, wo sie einen Mehrwert bieten (Paginierung, verwandte Ressourcen, Aktionen), zwingen die Clients aber nicht dazu, vollständig hypermedia-gesteuert zu sein.
In diesem Leitfaden erfahren Sie, was HATEOAS ist, warum es umstritten ist und wie Sie praktische Hypermedia-Links mithilfe der Modern PetstoreAPI als Referenz implementieren können.
Was ist HATEOAS?
HATEOAS ist eine REST-Einschränkung, die besagt, dass Clients API-Funktionen über Hypermedia-Links entdecken sollten, nicht über Dokumentation.
Das Konzept
Anstatt URLs fest zu codieren:
// Client hardcodes URLs
const response = await fetch('https://petstoreapi.com/v1/pets/123');
const pet = await response.json();
// Client knows the URL structure
await fetch(`https://petstoreapi.com/v1/pets/${pet.id}/orders`);
Clients folgen Links aus den Antworten:
// Client starts at root
const root = await fetch('https://petstoreapi.com/v1');
const rootData = await root.json();
// Client follows link to pets
const petsUrl = rootData._links.pets.href;
const pets = await fetch(petsUrl);
const petsData = await pets.json();
// Client follows link to specific pet
const petUrl = petsData._links.self.href;
const pet = await fetch(petUrl);
const petData = await pet.json();
// Client follows link to orders
const ordersUrl = petData._links.orders.href;
const orders = await fetch(ordersUrl);
Die Theorie
Mit HATEOAS:
1. Clients codieren URLs nicht fest
URLs können sich ändern, ohne Clients zu beeinträchtigen. Der Server kontrolliert die URL-Struktur.
2. Clients entdecken Funktionen
Wenn ein Link existiert, ist die Aktion verfügbar. Wenn nicht, ist sie nicht verfügbar (oder für diesen Benutzer nicht zulässig).
3. APIs sind selbstdokumentierend
Clients erkunden die API, indem sie Links folgen, ähnlich wie beim Surfen auf einer Website.
Beispiel: Vollständige HATEOAS-Antwort
{
"id": "019b4132-70aa-764f-b315-e2803d882a24",
"name": "Fluffy",
"species": "CAT",
"status": "AVAILABLE",
"_links": {
"self": {
"href": "https://petstoreapi.com/v1/pets/019b4132-70aa-764f-b315-e2803d882a24"
},
"update": {
"href": "https://petstoreapi.com/v1/pets/019b4132-70aa-764f-b315-e2803d882a24",
"method": "PUT"
},
"delete": {
"href": "https://petstoreapi.com/v1/pets/019b4132-70aa-764f-b315-e2803d882a24",
"method": "DELETE"
},
"orders": {
"href": "https://petstoreapi.com/v1/pets/019b4132-70aa-764f-b315-e2803d882a24/orders"
},
"adopt": {
"href": "https://petstoreapi.com/v1/pets/019b4132-70aa-764f-b315-e2803d882a24/adopt",
"method": "POST"
}
}
}
Der Client muss keine URL-Muster kennen. Er folgt Links.
Die HATEOAS-Debatte
HATEOAS ist umstritten, weil Theorie und Praxis auseinandergehen.
Argumente für HATEOAS
1. Lose Kopplung
Clients sind nicht von der URL-Struktur abhängig. Der Server kann URLs ändern, ohne Clients zu beeinträchtigen.
2. Entdeckbarkeit
Clients können die API erkunden, ohne Dokumentation lesen zu müssen.
3. Zustandsgesteuerte Aktionen
Links zeigen, welche Aktionen verfügbar sind. Wenn ein Haustier adoptiert wird, verschwindet der „adopt“-Link.
4. Echtes REST
Roy Fielding sagt, HATEOAS sei essenziell für REST. Ohne es betreiben Sie kein REST.
Argumente gegen HATEOAS
1. Komplexität
Clients benötigen eine Hypermedia-Parsing-Logik. Einfache HTTP-Clients werden zu komplexen Zustandsmaschinen.
2. Leistung
Clients stellen mehrere Anfragen, um URLs zu entdecken. Direkter URL-Zugriff ist schneller.
3. Schwierigkeiten beim Debuggen
Dem Folgen von Links erschwert das Debuggen. Sie können nicht einfach eine URL curl-en – Sie müssen der Linkkette folgen.
4. Mangelhafte Tools
Die meisten HTTP-Clients, Test-Tools und Dokumentationsgeneratoren gehen von festcodierten URLs aus.
5. Niemand tut es
GitHub, Stripe, Twilio, Twitter – große APIs verwenden kein vollständiges HATEOAS. Wenn sie es nicht brauchen, brauchen Sie es dann?
Die Realität
Die meisten APIs behaupten, „REST“ zu sein, verzichten aber auf HATEOAS. Es handelt sich eigentlich um „HTTP-APIs“ oder „REST-ähnliche APIs“. Echtes REST (mit HATEOAS) ist selten.
Praktische Hypermedia-Links
Anstatt vollständiges HATEOAS zu verwenden, nutzen Sie Hypermedia-Links dort, wo sie einen Mehrwert bieten.
1. Paginierungs-Links
Problem: Clients müssen Paginierungs-URLs konstruieren.
Lösung: Bereitstellung von Links für Nächste/Vorherige.
{
"data": [...],
"pagination": {
"page": 2,
"limit": 20,
"totalPages": 10
},
"links": {
"self": "https://petstoreapi.com/v1/pets?page=2&limit=20",
"first": "https://petstoreapi.com/v1/pets?page=1&limit=20",
"prev": "https://petstoreapi.com/v1/pets?page=1&limit=20",
"next": "https://petstoreapi.com/v1/pets?page=3&limit=20",
"last": "https://petstoreapi.com/v1/pets?page=10&limit=20"
}
}
Vorteil: Clients konstruieren keine Paginierungs-URLs. Sie folgen Links.
2. Links zu verwandten Ressourcen
Problem: Clients müssen URL-Muster für verwandte Ressourcen kennen.
Lösung: Bereitstellung von Links zu verwandten Ressourcen.
{
"id": "019b4132-70aa-764f-b315-e2803d882a24",
"name": "Fluffy",
"_links": {
"self": "https://petstoreapi.com/v1/pets/019b4132-70aa-764f-b315-e2803d882a24",
"orders": "https://petstoreapi.com/v1/pets/019b4132-70aa-764f-b315-e2803d882a24/orders",
"owner": "https://petstoreapi.com/v1/users/019b4127-54d5-76d9-b626-0d4c7bfce5b6"
}
}
Vorteil: Clients entdecken verwandte Ressourcen ohne Dokumentation.
3. Aktions-Links
Problem: Clients müssen wissen, welche Aktionen verfügbar sind.
Lösung: Bereitstellung von Links für verfügbare Aktionen.
{
"id": "019b4132-70aa-764f-b315-e2803d882a24",
"status": "AVAILABLE",
"_links": {
"adopt": {
"href": "https://petstoreapi.com/v1/pets/019b4132-70aa-764f-b315-e2803d882a24/adopt",
"method": "POST"
}
}
}
Wenn das Haustier bereits adoptiert wurde:
{
"id": "019b4132-70aa-764f-b315-e2803d882a24",
"status": "ADOPTED",
"_links": {
// No "adopt" link - action not available
}
}
Vorteil: Links zeigen verfügbare Aktionen basierend auf dem Status an.
4. Cursor-basierte Paginierung
Problem: Clients müssen Cursor-URLs konstruieren.
Lösung: Bereitstellung von undurchsichtigen Links für Nächste/Vorherige.
{
"data": [...],
"links": {
"next": "https://petstoreapi.com/v1/pets?cursor=eyJpZCI6IjAxOWI0MTMyIn0"
}
}
Vorteil: Clients parsen keine Cursor. Sie folgen Links.
Wie die Modern PetstoreAPI Hypermedia nutzt
Modern PetstoreAPI nutzt selektive Hypermedia-Links.
Paginierungs-Links
Alle Kollektions-Endpunkte enthalten Paginierungs-Links:
GET /v1/pets?limit=20
{
"data": [...],
"pagination": {
"limit": 20,
"hasMore": true
},
"links": {
"self": "https://petstoreapi.com/v1/pets?limit=20",
"next": "https://petstoreapi.com/v1/pets?cursor=eyJpZCI6IjAxOWI0MTMyIn0&limit=20"
}
}
Links zu verwandten Ressourcen
Ressourcen-Antworten enthalten Links zu verwandten Ressourcen:
GET /v1/pets/019b4132-70aa-764f-b315-e2803d882a24
{
"id": "019b4132-70aa-764f-b315-e2803d882a24",
"name": "Fluffy",
"ownerId": "019b4127-54d5-76d9-b626-0d4c7bfce5b6",
"_links": {
"self": "https://petstoreapi.com/v1/pets/019b4132-70aa-764f-b315-e2803d882a24",
"owner": "https://petstoreapi.com/v1/users/019b4127-54d5-76d9-b626-0d4c7bfce5b6",
"orders": "https://petstoreapi.com/v1/pets/019b4132-70aa-764f-b315-e2803d882a24/orders"
}
}
Kein vollständiges HATEOAS
Die Modern PetstoreAPI verlangt von Clients nicht, hypermedia-gesteuert zu sein. Clients können:
Option 1: Links folgen (hypermedia-gesteuert)
const pet = await fetch(petUrl);
const ownerUrl = pet._links.owner.href;
const owner = await fetch(ownerUrl);
Option 2: URLs konstruieren (traditionell)
const pet = await fetch(`https://petstoreapi.com/v1/pets/${petId}`);
const owner = await fetch(`https://petstoreapi.com/v1/users/${pet.ownerId}`);
Beide Ansätze funktionieren. Links werden zur Bequemlichkeit bereitgestellt, nicht zur Erzwingung.
Testen von Hypermedia-APIs mit Apidog
Apidog hilft Ihnen, Hypermedia-Links zu testen und die Korrektheit der Links zu validieren.
Test der Link-Präsenz
Verifizieren Sie, dass Antworten erwartete Links enthalten:
// Apidog test script
pm.test("Response includes pagination links", () => {
const links = pm.response.json().links;
pm.expect(links).to.have.property('self');
pm.expect(links).to.have.property('next');
});
Test der Link-Gültigkeit
Folgen Sie Links und überprüfen Sie, ob sie funktionieren:
// Apidog test script
const nextUrl = pm.response.json().links.next;
pm.sendRequest(nextUrl, (err, response) => {
pm.test("Next link returns 200", () => {
pm.expect(response.code).to.equal(200);
});
});
Test des Link-Formats
Verifizieren Sie, dass Links dem erwarteten Format folgen:
pm.test("Links are absolute URLs", () => {
const links = pm.response.json().links;
Object.values(links).forEach(link => {
pm.expect(link).to.match(/^https:\/\//);
});
});
Wann man HATEOAS verwenden sollte
Verwenden Sie Hypermedia-Links, wenn sie einen Mehrwert bieten. Lassen Sie sie weg, wenn nicht.
Hypermedia-Links verwenden für:
1. Paginierung – Clients sollten keine Paginierungs-URLs konstruieren
2. Verwandte Ressourcen – Bequeme Navigation
3. Zustandsabhängige Aktionen – Zeigen Sie verfügbare Aktionen basierend auf dem Ressourcenstatus an
4. Komplexe Workflows – Leiten Sie Clients durch mehrstufige Prozesse
HATEOAS überspringen für:
1. Einfache CRUD-APIs – Clients können URLs leicht konstruieren
2. Interne APIs – Teams können URL-Änderungen koordinieren
3. Performance-kritische APIs – Zusätzliche Links erhöhen die Antwortgröße
4. Mobile APIs – Bandbreite ist wichtig, Links verursachen Overhead
Fazit
HATEOAS ist theoretisch elegant, aber praktisch komplex. Die meisten APIs verzichten auf vollständiges HATEOAS und verwenden selektive Hypermedia-Links dort, wo sie einen Mehrwert bieten.
Modern PetstoreAPI demonstriert praktische Hypermedia: Paginierungs-Links, Links zu verwandten Ressourcen und Aktions-Links – ohne Clients zu zwingen, vollständig hypermedia-gesteuert zu sein.
Verwenden Sie Apidog zum Testen von Hypermedia-Links, zur Validierung der Link-Korrektheit und zur Sicherstellung, dass Ihre API eine nützliche Navigation bietet.
Wichtigste Erkenntnisse:
- Vollständiges HATEOAS ist selten und komplex
- Selektive Hypermedia-Links bieten Mehrwert ohne Komplexität
- Paginierungs-Links sind die nützlichste Hypermedia-Funktion
- Zwingen Sie Clients nicht, hypermedia-gesteuert zu sein
- Testen Sie Links, um sicherzustellen, dass sie korrekt funktionieren
Lesen Sie die Dokumentation der Modern PetstoreAPI, um die praktische Hypermedia-Implementierung zu sehen.
FAQ
Ist HATEOAS für REST-APIs erforderlich?
Laut Roy Fielding (Erfinder von REST) ja. In der Praxis nein. Die meisten „REST“-APIs verzichten auf HATEOAS und sind technisch gesehen „HTTP-APIs“ oder „REST-ähnliche APIs“.
Wofür steht HATEOAS?
Hypermedia as the Engine of Application State. Es bedeutet, dass Clients API-Funktionen über Hypermedia-Links entdecken, nicht über festcodierte URLs.
Verwenden große APIs HATEOAS?
Nein. GitHub, Stripe, Twilio und die meisten großen APIs verwenden kein vollständiges HATEOAS. Sie können einige Hypermedia-Links (Paginierung, verwandte Ressourcen) enthalten, verlangen aber nicht von Clients, hypermedia-gesteuert zu sein.
Was ist der Unterschied zwischen HATEOAS und Hypermedia-Links?
HATEOAS ist eine Einschränkung, die Clients dazu verpflichtet, vollständig hypermedia-gesteuert zu sein. Hypermedia-Links sind einfach Links in Antworten. Sie können Links einschließen, ohne HATEOAS durchzusetzen.
Sollte ich HATEOAS in meiner API implementieren?
Wahrscheinlich kein vollständiges HATEOAS. Verwenden Sie selektive Hypermedia-Links für Paginierung und verwandte Ressourcen. Zwingen Sie Clients nicht, hypermedia-gesteuert zu sein, es sei denn, Sie haben einen spezifischen Grund.
Wie teste ich HATEOAS-APIs?
Verwenden Sie Apidog, um die Link-Präsenz zu überprüfen, Links zu folgen und die Link-Korrektheit zu validieren. Testen Sie, ob Links die erwarteten Antworten zurückgeben.
Was ist das HAL-Format?
HAL (Hypertext Application Language) ist ein Standardformat für Hypermedia-Links. Es verwendet die Felder _links und _embedded. Die Modern PetstoreAPI verwendet ein HAL-inspiriertes Link-Format.
Können Clients Hypermedia-Links ignorieren?
Ja. Wenn Ihre API Links bereitstellt, aber nicht verlangt, dass Clients diese verwenden, können Clients URLs direkt konstruieren. Dies ist der pragmatische Ansatz, den die meisten APIs verfolgen.
