Teil III
Remote-APIs
8Grundlagen RESTful HTTP
Mit diesem Kapitel verlassen wir die Programmiersprachen-APIs und kommen zu den Remote-APIs, die eine explizite Grenze und häufig auch Interoperabilität zwischen API-Konsument und API-Anbieter gewährleisten, sodass Systeme unterschiedlichster Plattformen zusammen funktionieren können. Wer APIs bauen möchte, die tatsächlich die Bezeichnung »Webservice« verdienen, muss den Architekturstil des Web berücksichtigen. Deswegen bietet Ihnen dieses Kapitel wichtige Grundlagen über REST und HTTP.
8.1REST versus HTTP
Das Akronym REST steht für REpresentational State Transfer und wird in der Dissertation von Roy Fielding [Fielding 2000] erstmalig beschrieben. REST ist weder eine konkrete Technologie noch ein offizieller Standard. Es handelt sich vielmehr um einen Softwarearchitekturstil, bestehend aus Leitsätzen und bewährten Praktiken für netzwerkbasierte Systeme.
REST und HTTP werden häufig in einem Atemzug genannt. Das liegt daran, dass REST typischerweise mit HTTP umgesetzt wird. In diesem Fall spricht man von RESTful HTTP [Tilkov et al. 2015]. Doch nicht jede API, die HTTP verwendet, ist automatisch REST-konform. Außerdem ist HTTP nicht das einzige Protokoll, mit dem REST-konforme Applikationen realisiert werden können.
HTTP überträgt die Daten auf der Anwendungsschicht und ist vermutlich der wichtigste Standard im Web. HTTP basiert auf einem einfachen Request-Response-Modell, bei dem Nachrichten zwischen einem Client und einem entfernten Server über ein Netzwerk ausgetauscht werden. Ein Server kann eine Response-Nachricht nur als Antwort auf eine Request-Nachricht versenden.
In dieser Einführung werden die formalen Bedingungen des Architekturstils REST etwas vereinfacht, weil für dieses Buch nur RESTful HTTP interessant ist. Andere Umsetzungen der REST-Prinzipien werden nicht betrachtet. Daher soll nachfolgend REST immer im Sinne von RESTful HTTP verstanden werden.
8.2REST-Grundprinzipien
Die Grundprinzipien von REST kann man laut Stefan Tilkov et al. [Tilkov et al. 2015] folgendermaßen zusammenfassen:
- Eindeutige Identifikation von Ressourcen
- Verwendung von Hypermedia
- Verwendung von HTTP-Standardmethoden
- Unterschiedliche Repräsentationen von Ressourcen
- Statuslose Kommunikation
Was genau hinter diesen Grundprinzpien steht, wird im Einzelnen in den folgenden Abschnitten beschrieben.
Eindeutige Identifikation von Ressourcen
Jede Ressource braucht zur Identifikation einen eindeutigen Schlüssel. Stellen Sie sich vor, Sie könnten Videos auf YouTube, Tickets in Jira oder Produkte bei Amazon nicht eindeutig über Links identifizieren. Das wäre ziemlich unpraktisch, oder? Für das Web eignen sich für diese Aufgabe Uniform Resource Identifiers (URIs). Diese einheitlichen Bezeichner für Ressourcen bilden einen globalen Namensraum. Hier sind einige Beispiele:
http://example.com/answers/42
http://example.com/agents/agent-007/cars
http://example.com/users?locked=true
Man kann annehmen, dass die erste URI im obigen Beispiel genau eine Entität identifiziert. Es könnte die Antwort mit der ID 42 gemeint sein. Derartige menschenlesbare URIs werden nicht per se von REST verlangt, vereinfachen aber die Arbeit mit APIs. Auch die beiden anderen Beispiele sind intuitiv verständlich. Das zweite Beispiel identifiziert kein einzelnes Fahrzeug, sondern alle von Agent 007. Im dritten Beispiel werden alle gesperrten Benutzer selektiert.
In den letzten beiden Beispielen werden Collections identifiziert. Das ist jedoch kein Widerspruch zur Forderung, dass jede Ressource eine eindeutige Identifikation haben soll, denn Collections sind ebenfalls Ressourcen.
URI versus URL
URIs und URLs sind zusammen in RFC 3986 [Fielding & Masinter 2005] definiert. In den meisten Fällen (wie auch in diesem Buch) können URIs und URLs synonym verwendet werden, denn jede URL ist per Definition auch eine URI. Das gilt aber nicht umgekehrt: Nicht jede URI ist auch eine URL. Deswegen soll an dieser Stelle einmal deren Unterschied erklärt werden.
Eine URL ist eine kurze Zeichenkette, die eine Ressource identifiziert. Eine URI ist ebenfalls eine kurze Zeichenkette, die eine Ressource identifiziert. Was ist der Unterschied?
Eine URI ist in erster Linie ein eindeutiger Identifikator und es gibt keine Garantie, dass für diesen eine Repräsentation existiert. Ein XML-Namensraum heißt typischerweise nicht »User«, weil diese Bezeichnung höchstwahrscheinlich nicht eindeutig wäre. Auch andere Entwickler könnten diesen Namen verwenden. Folglich wählt man einen Namen wie »http://mycompany.com/person«. Diese Bezeichnung ist eindeutig und ein Konflikt mit anderen Namensräumen sehr unwahrseinlich. Der Name des XML-Namensraums ist somit eine URI, aber ist der Name auch eine URL? Nein. Denn es gibt nicht notwendigerweise eine Repräsentation, die man unter dieser URI aufrufen könnte.
Übrigens ist auch eine URN (Uniform Resource Name) eine URI [Berners-Lee et al. 1998], die dauerhaft und ortsunabhängig nach dem urn-Schema eine Ressource identifiziert. Mit der ISBN eines Buches kann beispielsweise eine URN für das Buch gebildet werden. Sie enthält auch keine Protokollangaben (http, ftp, amqp etc.), mit der ein Client versuchen könnte, sie aufzurufen.
Verwendung von Hypermedia
Der Begriff Hypermedia ist eine Mischung aus »Hypertext« und »Multimedia«. Das griechische Präfix »hyper« (ύπέρ) kann mit »über« und »hinaus« übersetzt werden. Daher ist mit Hypertext ein Text gemeint, der über sich selbst hinaus weist. Hypermedia ist ein Oberbegriff von Hypertext. Während also Hypertext ausschließlich Texte verknüpft, schließt Hypermedia auch Dokumente, Bilder, Töne, Videos und andere multimedialen Inhalte mit ein.
Ein wesentliches Merkmal von Hypermedia stellen Links zur Verknüpfung verschiedener Medien dar. Links sind vor allem durch HTML sehr gut bekannt. Mit einem Browser kann man den Links leicht folgen. Sie dienen zur Ausführung von Aktionen und zur Navigation im Web. HTML ist daher ein klassisches Hypermediaformat. Die für den Client möglichen Aktionen und Navigationspfade werden vom Server über Hypermedia angeboten.
Aber selbstverständlich können auch andere Formate mit Links verbunden werden. Das folgende XML-Beispiel zeigt eine Nachricht, deren Anhang nicht in die Nachricht eingebettet ist, sondern mittels einer URI referenziert wird.
<message self="http://example.com/messages/17">
<body>...</body>
<attachment ...