Wie nützlich / wichtig ist REST HATEOAS (Reifegrad 3)?

110

Ich beteilige mich an einem Projekt, bei dem einige hochrangige Teammitglieder der Meinung sind, dass eine REST-API HATEOAS-konform sein und alle Richardson-Reifegrade implementieren muss ( http://martinfowler.com/articles/richardsonMaturityModel.html )!

AFAIK Die meisten REST-Implementierungen sind nicht HATEOAS-konform und es sollte einen guten Grund geben, warum mehr Leute dies nicht tun. Ich kann mir Gründe wie zusätzliche Komplexität, fehlende Frameworks (Server- und Client-Seite), Leistungsprobleme und ...

Was denken Sie? Haben Sie Erfahrungen mit HATEOAS in einem realen Projekt gemacht?

mhdwrk
quelle
Hier ist ein guter Artikel zu diesem Thema: medium.com/@andreasreiser94/… Grundsätzlich ist die Art und Weise, wie "REST" normalerweise implementiert wird, RPC ...
masterxilo

Antworten:

213

Niemand in der REST-Community sagt, dass REST einfach ist. HATEOAS ist nur einer der Aspekte, die einer REST-Architektur Schwierigkeiten bereiten.

Die Leute machen HATEOAS nicht aus all den Gründen, die Sie vorschlagen: Es ist schwierig. Dies erhöht die Komplexität sowohl auf der Serverseite als auch auf dem Client (wenn Sie tatsächlich davon profitieren möchten).

Milliarden von Menschen erleben heute jedoch die Vorteile von REST. Wissen Sie, wie die "Checkout" -URL bei Amazon lautet? Ich nicht. Trotzdem kann ich jeden Tag auschecken. Hat sich diese URL geändert? Ich weiß nicht, es ist mir egal.

Weißt du, kümmert es dich? Jeder, der einen Bildschirm geschrieben hat, hat den automatisierten Amazon-Client abgekratzt. Jemand, der wahrscheinlich akribisch den Webverkehr beschnüffelt, HTML-Seiten gelesen usw. hat, um herauszufinden, welche Links wann und mit welchen Nutzdaten aufgerufen werden müssen.

Und sobald Amazon seine internen Prozesse und die URL-Struktur geändert hat, sind diese fest codierten Clients fehlgeschlagen - weil die Links unterbrochen wurden.

Die Gelegenheits-Surfer konnten jedoch den ganzen Tag ohne Probleme einkaufen.

Das ist REST in Aktion, es wird nur durch den Menschen ergänzt, der in der Lage ist, die textbasierte Oberfläche zu interpretieren und zu verstehen, eine kleine Grafik mit einem Einkaufswagen zu erkennen und herauszufinden, was das eigentlich bedeutet.

Die meisten Leute, die Software schreiben, tun das nicht. Die meisten Leute, die automatisierte Clients schreiben, kümmern sich nicht darum. Die meisten Leute finden es einfacher, ihre Clients zu reparieren, wenn sie kaputt gehen, als die Anwendung so zu konstruieren, dass sie überhaupt nicht kaputt geht. Die meisten Leute haben einfach nicht genug Kunden, wo es darauf ankommt.

Wenn Sie eine interne API für die Kommunikation zwischen zwei Systemen mit fachkundigem technischen Support und IT auf beiden Seiten des Datenverkehrs schreiben, die Änderungen schnell, zuverlässig und mit einem Zeitplan für Änderungen kommunizieren können, kauft REST Ihnen nichts. Sie brauchen es nicht, Ihre App ist nicht groß genug und es ist nicht lang genug, um eine Rolle zu spielen.

Große Websites mit einer großen Benutzerbasis haben dieses Problem. Sie können die Leute nicht einfach bitten, ihren Client-Code aus einer Laune heraus zu ändern, wenn sie mit ihren Systemen interagieren. Der Zeitplan für die Serverentwicklung stimmt nicht mit dem Zeitplan für die Cliententwicklung überein. Abrupte Änderungen an der API sind für alle Beteiligten einfach nicht akzeptabel, da sie den Datenverkehr und den Betrieb auf beiden Seiten stören.

Ein solcher Vorgang würde also sehr wahrscheinlich von HATEOAS profitieren, da es einfacher zu versionieren ist, für ältere Clients einfacher zu migrieren ist und einfacher abwärtskompatibel ist als nicht.

Ein Client, der einen Großteil seines Arbeitsablaufs an den Server delegiert und auf die Ergebnisse reagiert, ist gegenüber Serveränderungen wesentlich robuster als ein Client, der dies nicht tut.

Aber die meisten Leute brauchen diese Flexibilität nicht. Sie schreiben Servercode für 2 oder 3 Abteilungen, alles für den internen Gebrauch. Wenn es kaputt geht, beheben sie es und haben dies in ihren normalen Betrieb einbezogen.

Flexibilität, ob von REST oder irgendetwas anderem, führt zu Komplexität. Wenn Sie es einfach und schnell wollen, dann machen Sie es nicht flexibel, Sie "machen es einfach" und fertig. Wenn Sie Abstraktionen und Dereferenzierungen zu Systemen hinzufügen, wird es schwieriger, mehr Kesselplatten und mehr Code zum Testen.

Ein Großteil von REST verfehlt den Aufzählungspunkt "Sie werden es nicht brauchen". Bis du es natürlich tust.

Wenn Sie es brauchen, verwenden Sie es und verwenden Sie es so, wie es angelegt ist. REST schiebt keine Dinge über HTTP hin und her. Es war noch nie so, es ist viel höher.

Aber wenn Sie REST benötigen und REST verwenden, ist HATEOAS eine Notwendigkeit. Es ist Teil des Pakets und ein Schlüssel dafür, wie es überhaupt funktioniert.

Will Hartung
quelle
11
Ich denke, Sie sollten mindestens tausend weitere Likes für diese Antwort haben. Ehrlich gesagt muss ich mir Folgendes vorstellen: Wie wichtig es ist, eine "echte" REST-Frage zu sein, kommt ziemlich oft auf. Zur Hölle, ich habe aus genau diesem Grund gegoogelt, damit Munition in einem bevorstehenden Meeting verwendet werden kann, als ich diesen Thread gefunden habe.
Nograde
2
Gott sei Dank (oder Code) spricht jemand auch über die Nachteile von HATEOAS!
IlliakaillI
6
Gibt es einen anderen Vorteil als die Möglichkeit, URLs einfach zu ändern? Sie können nicht einfach neue Optionen hinzufügen, da das Programm im Gegensatz zu Menschen nicht mit etwas Neuem arbeiten kann. Außerdem haben Sie nur vom Erstellen wissender URLs zum Erkennen des Namens von Aktionen gewechselt.
Jimmy T.
Wenn der API-Konsument nichts weiß, kann er Benutzeraktionen nur 1: 1
Jimmy T.
2
Vergessen Sie beim Ändern von URLs nicht, dass Ihr Client möglicherweise einen Cache verwendet. Daher müssen Sie das Verhalten auf dem Server beibehalten, um auch die vorherige URL zu verarbeiten (oder einfach eine Umleitung durchführen). Wie bei jeder Strategie zur Entwicklung von APIs müssen Sie Ihr altes Verhalten beibehalten. HATEOAS hilft dort nicht viel.
Bruno Costa
21

Ja, ich habe einige Erfahrungen mit Hypermedia in APIs gemacht. Hier sind einige der Vorteile:

  1. Explorierbare API: Es mag trivial klingen, aber unterschätzen Sie nicht die Leistungsfähigkeit einer explorierbaren API. Die Möglichkeit, die Daten zu durchsuchen, erleichtert es den Client-Entwicklern erheblich, ein mentales Modell der API und ihrer Datenstrukturen zu erstellen.

  2. Inline-Dokumentation: Die Verwendung von URLs als Link-Relationen kann Client-Entwickler auf die Dokumentation verweisen.

  3. Einfache Client-Logik: Ein Client, der URLs einfach folgt, anstatt sie selbst zu erstellen, sollte einfacher zu implementieren und zu warten sein.

  4. Der Server übernimmt das Eigentum an URL-Strukturen: Durch die Verwendung von Hypermedia wird dem Client das fest codierte Wissen über die vom Server verwendeten URL-Strukturen entzogen.

  5. Laden von Inhalten auf andere Dienste: Hypermedia ist erforderlich, wenn Inhalte auf andere Server (z. B. ein CDN) geladen werden.

  6. Versionierung mit Links: Hypermedia hilft bei der Versionierung von APIs.

  7. Mehrere Implementierungen desselben Dienstes / derselben API: Hypermedia ist erforderlich, wenn mehrere Implementierungen desselben Dienstes / derselben API vorhanden sind. Ein Dienst kann beispielsweise eine Blog-API mit Ressourcen zum Hinzufügen von Posts und Kommentaren sein. Wenn der Dienst in Bezug auf Linkbeziehungen anstelle von fest codierten URLs angegeben wird, kann derselbe Dienst unter verschiedenen URLs mehrfach instanziiert werden, die von verschiedenen Unternehmen gehostet werden, aber dennoch über denselben genau definierten Satz von Links von einem einzelnen Client zugänglich sind.

Eine ausführliche Erläuterung dieser Aufzählungspunkte finden Sie hier: http://soabits.blogspot.no/2013/12/selling-benefits-of-hypermedia.html

(Es gibt hier eine ähnliche Frage: /software/149124/what-is-the-benefit-of-hypermedia-hateoas, wo ich die gleiche Erklärung gegeben habe)

Jørn Wildt
quelle
Mehrere Implementierungen desselben Dienstes: Können Sie dies näher erläutern? Ich sehe nicht, wie es hilft.
Abbadon
Ich habe versucht, es im Text zu erklären. Hilft es?
Jørn Wildt
11

Richardsons Reifegrad 3 ist wertvoll und sollte übernommen werden. Jørn Wildt hat bereits einige Vorteile zusammengefasst und eine andere Antwort von Wilt ergänzt sie sehr gut.

Der Reifegrad 3 von Richardson ist jedoch nicht der gleiche wie der von HINGEOAS von Fielding. Bei Richardsons Reifegrad 3 geht es nur um API-Design. In Fieldings HATEOAS geht es auch um API-Design, es wird jedoch auch vorgeschrieben, dass die Client-Software nicht davon ausgehen sollte, dass eine Ressource eine bestimmte Struktur aufweist, die über die durch den Medientyp definierte Struktur hinausgeht. Dies erfordert einen sehr allgemeinen Client wie einen Webbrowser, der keine Kenntnisse über bestimmte Websites hat. Da Roy Fielding den Begriff REST geprägt und HATEOAS als Voraussetzung für die Einhaltung von REST festgelegt hat, lautet die Frage: Wollen wir HATEOAS übernehmen und wenn nicht, können wir unsere API trotzdem als RESTful bezeichnen oder nicht? Ich denke wir können. Lassen Sie mich erklären.

Angenommen, wir haben HATEOAS erreicht. Die Clientseite der Anwendung ist jetzt sehr allgemein gehalten, aber höchstwahrscheinlich ist die Benutzererfahrung schlecht, da die Darstellung der Ressourcen ohne Kenntnis der Semantik der Ressourcen nicht auf diese Semantik zugeschnitten werden kann. Wenn die Ressource 'Auto' und die Ressource 'Haus' denselben Medientyp haben (z. B. Anwendung / JSON), werden sie dem Benutzer auf dieselbe Weise angezeigt, beispielsweise als Eigenschaftentabelle (Name / Wert-Paare).

Aber okay, unsere API ist wirklich RESTful.

Angenommen, wir erstellen eine zweite Clientanwendung auf dieser API. Dieser zweite Kunde verstößt gegen die HATEOAS-Ideen und verfügt über fest codierte Informationen zu den Ressourcen. Es zeigt ein Auto und ein Haus auf unterschiedliche Weise.

Kann die API weiterhin als RESTful bezeichnet werden? Ich glaube schon. Es ist nicht die Schuld der API, dass einer ihrer Clients gegen HATEOAS verstoßen hat.

Ich empfehle, RESTful-APIs zu erstellen, dh APIs, für die ein generischer Client theoretisch implementiert werden kann. In den meisten Fällen benötigen Sie jedoch einige fest codierte Informationen zu Ressourcen in Ihrem Client, um die Usability-Anforderungen zu erfüllen. Versuchen Sie dennoch, so wenig wie möglich hart zu codieren, um die Abhängigkeiten zwischen Client und Server zu verringern.

Ich habe einen Abschnitt über HATEOAS in mein REST-Implementierungsmuster namens JAREST aufgenommen .

www.admiraalit.nl
quelle
8

Wir erstellen eine REST Level 3 API, bei der unsere Antwort in HAL-Json erfolgt. HATEOAS eignet sich sowohl für das Front- als auch für das Back-End, ist jedoch mit Herausforderungen verbunden. Wir haben einige Anpassungen / Ergänzungen vorgenommen, um auch die ACL innerhalb der HAL-Json-Antwort zu verwalten (was den HAL-Json-Standard nicht verletzt).

Der größte Vorteil von HATEOAS ist, dass wir keine URLs in unserer Front-End-Anwendung schreiben / erraten müssen. Sie benötigen https://hostnamelediglich einen Einstiegspunkt ( ) und können von dort aus mithilfe der in der Antwort enthaltenen Links oder Vorlagenlinks einfach durch die Ressourcen blättern. Auf diese Weise kann die Versionierung einfach gehandhabt werden, indem URLs umbenannt / ersetzt werden und Ressourcen mit zusätzlichen Beziehungen erweitert werden, ohne dass der Front-End-Code beschädigt wird.

Das Zwischenspeichern von Ressourcen im Front-End ist über die Self-Links ein Kinderspiel. Wir übertragen Ressourcen auch über eine Socket-Verbindung an Clients, da diese auch in HAL gerendert werden. Wir können sie auf die gleiche Weise problemlos zum Cache hinzufügen.

Ein weiterer Vorteil der Verwendung von HAL-Json besteht darin, dass klar ist, wie das Antwortmodell aussehen soll, da ein dokumentierter Standard befolgt werden sollte.

Eine unserer Anpassungen ist , dass wir ein Objekt innerhalb des Aktionen selbstVerknüpfungsObjekt dass aussetzt an dem vorderen Ende , welche Aktionen oder Operationen CRUD der authentifizierte Benutzer darf auszuführen auf der jeweiligen Ressource hinzugefügt ( create:POST, read:GET, update:PUT, edit:PATCH, delete:DELETE). Auf diese Weise wird unsere Front-End-ACL vollständig von unserer REST-API-Antwort bestimmt, wodurch diese Verantwortung vollständig auf das Back-End-Modell übertragen wird.

Um ein kurzes Beispiel zu geben: Sie könnten ein Post-Objekt in HAL-Json haben, das ungefähr so ​​aussieht:

{
    "_links": {
        "self": {
            "href": "https://hostname/api/v1/posts/1",
            "actions": {
                "read": "GET",
                "update": "PUT",
                "delete": "DELETE"
            }
        }
    },
    "_embedded": {
        "owner": {
            "id": 1,
            "name": "John Doe",
            "email": "[email protected]",
            "_links": {
                "self": {
                    "href": "https://hostname/api/v1/users/1",
                    "actions": {
                        "read": "GET"
                    }
                }
            }
        }
    },
    "subject": "Post subject",
    "body": "Post message body"
}

Jetzt müssen wir auf Front - End zu tun haben , ist ein Build AclServicemit einem isAllowedVerfahren , dass überprüft , ob die Handlung , die wir ausführen wollen , ist in den Aktionen widersprechen .

Derzeit sieht es im Frontend so einfach aus wie: post.isAllowed('delete');

Ich denke, REST Level 3 ist großartig, aber es kann zu Kopfschmerzen führen. Sie müssen ein gutes Verständnis für REST haben. Wenn Sie mit REST der Stufe 3 arbeiten möchten, würde ich empfehlen, das REST-Konzept strikt zu befolgen, da Sie sich sonst bei der Implementierung leicht verirren.

In unserem Fall haben wir den Vorteil, dass wir sowohl Front- als auch Back-End bauen, aber im Prinzip sollte es keinen Unterschied machen. Eine häufige Gefahr, die ich in unserem Team gesehen habe, ist, dass einige Entwickler versuchen, Front-End-Probleme (Architektur) zu lösen, indem sie ihr Back-End-Modell so ändern, dass es den Front-End-Anforderungen "entspricht".

Verwelken
quelle
1
Sehr gute Antwort. Ich denke, ein solches praktisches Beispiel war das, wonach der ursprüngliche Fragesteller gesucht hat.
www.admiraalit.nl
2

Ich habe HATEOAS in einigen realen Projekten verwendet, aber mit einer anderen Interpretation als Richardson. Wenn es das ist, was Ihre Chefs wollen, dann sollten Sie es einfach tun. Ich verstehe unter HATEOAS, dass Ihre Ressourcen einen HTML-Doctype, Hyperlinks zu verwandten Ressourcen und HTML-Formulare enthalten sollten, um Funktionen für andere Verben als GET bereitzustellen. (Dies ist der Fall, wenn der Akzeptiertyp Text / HTML ist - andere Inhaltstypen erfordern diese Extras nicht.) Ich weiß nicht, woher die Überzeugung stammt, dass alle REST-Ressourcen in Ihrer gesamten Anwendung zusammengeklebt werden müssen. Eine Netzwerkanwendung sollte mehrere Ressourcen enthalten, die möglicherweise in direktem Zusammenhang stehen oder nicht. Oder warum angenommen wird, dass XML, JSON und andere Typen dies befolgen müssen. (HATEOAS ist HTML-spezifisch.)

Chris Broski
quelle