HATEOAS mit Spring Boot

HATEOAS steht für Hypermedia as the Engine of Application State.

Einige bezeichnen es für REST-Schnittstellen als unverzichtbar. (heise)

Das Prinzip wurde von Roy Fielding erstmals in seiner Doktorarbeit beschrieben und später in seinem Blog weiter vertieft.

Doch warum findet man es so selten in REST Schnittstellen? Bisher sehe ich fast nie Anwendungen, die HATEOAS wirklich praktizieren. Doch wieso ist das so?

Um Schnittstellen zu dokumentieren, verwenden viele Swagger (was grundlegend sehr gut ist und ein Fortschritt zu nichts). Doch wie wäre es, wenn man hier statt der SwaggerUI direkt die Links in der Antwort hätte?

Was ist Hypermedia?

Hypermedia ist die Vernetzung von Medien mit Hyperlinks, also Links zu anderen Resourcen.

Das gesamte Internet besteht im Prinzip aus Hyperlinks. Ein Aufruf auf Google gibt einem eine HTML (Hypertext Markup Language) Seite zurück, welche aus Links besteht. Durch das Klicken, kommen wir zur nächsten Seite usw. Somit Folgen wir nur Links. Der Name HTML enthält Hypertext, also ähnlich zu Hypermedia, nur, dass es nur Text sein kann und nichts anderes wie Bilder, Videos oder ähnliches.

REST Level

Es gibt im Grunde 4 Rest-Level, welche immer spezifischer werden, je detaillierter man sie betrachtet.

Reiner Text oder XML, welcher per Post hin und her gesendet wird.

Jede Resource hat ihre eigene URL.

HTTP Aktionen, also POST, GET, PUT, DELETE,…
Unterstützt eine Schnittstelle diese, ist sie bereits Level 2

Das höchste und detailierteste Level ist HATEOAS, also Level 3.

Am Beispiel

Das Konzept besteht darauf, dass eine Antwort immer die nächsten möglichen Schritte enthält, und die Links dazu bereitstellt. Im Grunde wie ein Zustandsautomat, welcher auf der Resource abgebildet ist.

Am Beispiel lässt es sich am besten zeigen. Stellen wir uns eine Resource vor, welche users und roles bereitstellt. Von roles aus können wir die Details einer Rolle mit Liste der Nutzer mit der Rolle abrufen und die detaillierte Rolle. Von users aus, können wir uns die Details eines Nutzers abrufen.

Das könnte folgendermaßen aussehen:

Mit Spring Boot

Wollen wir eine wie oben beschriebene Schnittstelle umsetzen, können wir dies Beispielsweise mit Spring HATEOAS bewerkstelligen.

Im Folgenden werde ich Beispielhaft zeigen, wie man das Diagramm von oben mit Spring umsetzen kann. Das Projekt ist auf GitHub verfügbar.

Im ersten Schritt erstellen wir uns eine Schnittstelle:

Hier wurde nun eine Funktion erstellt, die einen bestimmten User zurückgibt. Die Methode linkTo kommt von Spring HATEOAS WebMvcLinkBuilder. Sie erstellt einen Linkt zu der Methode, welche referenziert wird, mit einer Relation. Also entweder auf sich selbst oder mit einem String als Referenz. Das ganze sieht dann im Response so aus:

Wie wir sehen, sind die Links enthalten, sowohl auf sich selbst, als auch zurück auf users.

Den genauen Code kann man sich auf GitHub ansehen.

Wichtig zu wissen ist, dass es bei Spring HATEOAS zwei Typen des Responses gibt. EntityModel, was eine einzelne Entität ist und CollectionModel, welches eine Liste von Entitäten ist.

Zusammenfassung

Es gibt leider keinen klaren Standard für HATEOAS, daher muss man noch relativ viel selbst implementieren. Schön ist hier die Bibliothek von Spring, welche im September 2019 ihr 1.0 Release hatte. Hier funktioniert auch das Lesen der Links gut und es fühlt sich schon an, als ob man damit stabil arbeiten kann.

Ein großer Vorteil ist, dass sich Links beliebig ändern können und der Client nicht angepasst werden muss, da er nur auf die Referenz zugreift. So bleibt der Link komplett in der Hand des Backends.

Den größten Vorteil sehe ich allerdings im Bereich der Berechtigungen. Hierbei kann eine Relation einfach ein- oder ausgeblendet werden, sofern ein Nutzer das Recht oder eben nicht das Recht hat, diese Aktion durchzuführen. Dabei muss der Client keine Logik enthalten, ob er nun ein Element löschen darf oder nicht, da er die Referenz zu dem Link nur erhält, wenn er es darf. Damit ermöglicht man beispielsweise auch Veränderungen der Applikation zur Laufzeit ohne Neudeployment. Hier kann ich das Video von Greg Turnquist auf Youtube zum Thema Spring HATEOAS 1.0 sehr empfehlen! Hier wird auch alles nochmal Detailliert erklärt.

Für mich gibt es eigentlich nur zwei.

  1. Eine Schnittstelle kann leichter durch Ausprobieren erforscht werden
  2. Es wird viel Boilerplate mitgesendet

Der erste Punkt ist für mich nicht ganz so relevant, da man entweder durch API Doc’s, Swagger oder die Anwendung selbst meist eh alle Endpunkte verrät. Hier muss der Server weitere Sicherheitsmaßnahmen wie Authentifizierung und Informationen zum Client mit abfragen und dementsprechend die Resourcen anders behandeln.

Der zweite Punkt ist etwas relevanter. Gerade wenn ich im Zug unterwegs bin, finde ich es sehr nervig, wenn Anwendungen langsam laden oder unresponsive sind. Doch denke ich, dass hier die paar Zeilen unwesentlich mehr Kosten verursachen und die Seiten wohl eher auf das ganze Tracking verzichten sollten. Hier sehe ich auch eher kein großes Hindernis.

Fazit

Ich finde HATEOAS sehr spannend und hoffe, dass sich das Thema durchsetzen wird, da es meiner Meinung nach für eine klarere und einfacher benutzbare Schnittstelle sorgt. Das Folgen von Links scheint intuitiv und ist das, was wir tagtäglich im Web tun. Also warum sollten das nicht auch unserer Anwendungen tun? Hier verhindert man in Zukunft vielleicht das ein oder andere mal das Typische /v1/, /v2/, /v3/… Api Design.

Danke fürs lesen, wenn es euch gefallen hat, lasst mir doch Applaus da. Schreibt mir gern auch ein Kommentar, ich werde schnellstmöglich reagieren :-)

☕️ →👨‍💻 // Developer @ SAP

☕️ →👨‍💻 // Developer @ SAP