© Spectral-Design/Shutterstock.com
Potenziale der Erstellung von RESTful APIs

Wie man REST (nicht) richtig macht


„Wir machen REST“ ist die ewig wiederkehrende Antwort auf die Frage nach dem Datentransfer zwischen Client und Server im Webkontext. REST (Representational State Transfer) scheint damit allgegenwärtig zu sein, immerhin ist REST ja auch ein allgemein akzeptiertes und modernes Schlagwort. Das birgt aber so manche Tücken.

Die Absurdität der pauschalen Aussage, dass REST die Antwort auf die Frage nach dem Datentransfer ist, manifestiert sich während der Analyse des betreffenden Systems oder der Anforderungen daran. Es existiert eine Vielzahl an unterschiedlichen Ausprägungen, die als RESTful bezeichnet werden. HTTP-basierte Interfaces werden pauschal als RESTful aufgefasst, weil sie zum Teil mit selbsternannten RESTful-API-Beschreibungssprachen dokumentiert wurden. Der Höhepunkt der Widersinnigkeit wird in einigen wenigen Fällen in der Gleichsetzung von REST mit JSON erreicht.

Dieser Artikel greift das grundlegende Missverständnis über RESTful APIs und HTTP-Interfaces auf und erläutert die nicht ausgeschöpften Möglichkeiten der Erstellung von RESTful APIs. Die Auffassung, das Web sei ein globales, verteiltes System, das gut skaliert einer losen Kopplung von Komponenten folgt und Funktionalitäten über Service-Grenzen hinweg miteinander verbindet, ist eine Perspektive, die Roy Fielding mit der Einführung des REST-Architekturstils in seiner Dissertation im Jahr 2000 verfolgte [1]. Er nahm damit enormen Einfluss auf die vom W3C publizierte Beschreibung des Webs („Architecture of the World Wide Web“ [2]), in der die Datenformate, Informationsbeschaffung und -speicherung konzeptionell beschrieben sind.

Fieldings Perspektive erweitert dieses Konzept um Bedingungen (Constraints), die dazu führen, dass das Web zur Ausführung von Aufgaben (Tasks) benutzt werden kann. Innerhalb eines verteilten Systems können demnach Aufgaben ausgeführt werden, indem durch den Aufruf einer Transition das System von einem Zustand in einen darauffolgenden Zustand überführt wird. Mit einer Transition ist die im jeweiligen Kontext auszuführende Aufgabe verbunden.

Abbildung 1 zeigt beispielhaft die Zustände eines Benutzers in einem System. Ein initial angelegter Benutzer kann durch die Transition save in den Folgezustand Inital, saved überführt werden. Mit diesem Zustandsübergang ist die Aufgabe des Speicherns, zum Beispiel in einer Datenbank, verknüpft. Der erste Log-in des Benutzers (Transition first login) aktiviert diesen im System (Überführung in den Zustand Active). An diesem Übergang kann zum Beispiel eine Aufgabe erfolgen, die nur einmalig bei dem ersten Log-in ausgeführt wird; beispielsweise das Abspielen eines Erste-Schritte-Videos. Ein solcher Zustandsautomat kann für jede Entität im System im Vorfeld spezifiziert werden, sofern die Zustände der jeweiligen Entität bekannt sind.

koschel_volkert_reiser_tiemeyer_REST_1.tif_fmt1.jpgAbb. 1: Beispielhafte Zustände eines Benutzers in einem System (Quelle: adesso AG)

Hypermedia as the Engine of Application State (HATEOAS)

Das Entscheidende an Fieldings Perspektive ist, dass im Unterschied zu einem Zustandsautomat die Transitionen und Zustände des Systems nicht zwingend im Vorfeld definiert sein müssen. Das funktioniert folgendermaßen: Innerhalb eines (verteilten) Systems existieren Ressourcen. Eine Ressource ist eine Abstraktion von Dingen, die ein System verwaltet oder definiert, beispielsweise gespeicherte Entitäten, HTML-Seiten oder -Fragmente, Dateien, Medien, Hardware usw. Auch das System selbst oder Teile daraus können als Ressource aufgefasst werden. Jede einzelne Ressource ist eindeutig identifizierbar, was beispielsweise durch die Zuordnung einer eindeutigen Identifikationsnummer zu einer Ressource sichergestellt werden kann. Laut Fielding kann der Status, in dem sich eine Ressource befindet, auch wieder als Ressource aufgefasst werden, ist somit eindeutig identifizierbar und darüber hinaus durch das System berechenbar. Dasselbe gilt dabei auch für die Status, die von diesem Status aus erreicht werden können.

Die Ressourcen und somit auch die Zustände einer jeweiligen Ressource können darüber hinaus nicht linear untereinander verknüpft sein. Das heißt: Von jeder Ressource aus kann eine Referenz auf eine oder mehrere andere Ressource(n) oder deren (Folge-)Zustand existieren, wodurch eine Vernetzung der Ressourcen entsteht. Diese Vernetzung kann dabei zum einen statisch definiert sein, zum anderen von dem System selbst dynamisch berechnet werden. Das System ermittelt dynamisch seine eigenen (Folge-)Zustände anhand definierter Regeln oder Aufgaben. Hierdurch ist das System selbst statuslos, da es keinen Zustand verwaltet. Jeder Zustand, in dem sich das System zu einem Zeitpunkt befindet, kann durch das System ausschließlich berechnet und wiederhergestellt werden.

Anhand von Repräsentationen der eindeutig identifizierbaren Ressourcen kann das System diese Status und die Folgestatus kommunizieren. Jede Ressource enthält dazu in ihrer Repräsentation die Identifikatoren der Status, in die das System vom aktuellen Zustand aus übergehen kann; die reflexive Transition in den aktuellen Status eingeschlossen.

Die Statusübergänge, die es ermöglichen, das System von einem Zustand in den nächsten zu transitieren, werden innerhalb der Repräsentation einer Ressour...

Neugierig geworden? Wir haben diese Angebote für dich:

Angebote für Gewinner-Teams

Wir bieten Lizenz-Lösungen für Teams jeder Größe: Finden Sie heraus, welche Lösung am besten zu Ihnen passt.

Das Library-Modell:
IP-Zugang

Das Company-Modell:
Domain-Zugang