Verteilte Anwendungen Teil 9: Representational State Transfer (REST) Teil 1 24.05.18 1
Literatur [9-1] Fielding, Roy Thomas: Architectural Styles and the Design of Network-based Software Architectures. http://www.ics.uci.edu/~fielding/pubs/dissertation/top.htm [9-2] Fielding, R.T.; Taylor R. N.: Principled Design of the Modern Web Architecture. ACM Transactions on Internet Technology, Vol. 2, No. 2, May 2002, Pages 115 150 htt ps://www.ics.uci.edu/~taylor/documents/2002-rest-toit.pdf [9-3] HTTP-Dedfinitionen: http://www.rfc-base.org/rfc-7231.html [9-4] HTTP/1.1: Semantics and Content https://tools.ietf.org/pdf/rfc7231.pdf [9-5] HTTP/1.1: Conditional Requests https://tools.ietf.org/pdf/rfc7232.pdf [9-6] Tikov, Stefan et a.: REST und HTTP. 3. Auflage, dpunkt, 2015 2
Übersicht HTTP (Wiederholung) REST-Prinzipien Konsequenzen Namenswahl Realisierung von Ressourcen 3
Hypertext Transfer Protokoll (HTTP) HTTP 1.1 definiert in RFC 7230 bis 7238 HTTP/2 (2.0) definiert in RFC 7540 Benutzung von Port 80 oder einem Port, der in der URL angegeben ist Aufbau einer URI/URL http://rechnername.subdomain.domain.top:port/dateiname? XXX=YYY... Angabe des Protokolls, hier http Angabe des Rechners, meist www Angabe der SubDomain entfällt meist Nach dem? folgen Zusatzinformationen Zusatzinformationen 4
HTTP als Client/Server- und Server/Server-Protokoll Übliche Verwendung mit Browsern Client Server Verwendung zwischen Servern 5
Referenzen Ressource Uniform Resource Identifier (URI) Ressource = "Betriebsmittel" = Mit URI adressiertes Objekt mit Daten und/oder Code Beispiele für Ressourcen Datei mit HTML Datei mit PHP-Code Graphik-Datei (*.gif, *.jpeg) Ladbare Klasse oder Modul(!) target resource = Ressource, die am Ende nach (optionalen) Weiterleitungen angesprochen wird 6
HTTP-Request Header Request Line Header Fields Payload MIME-Header Message Kopf = Header = Block von Informationen über die Anforderungen bzw. Antwort Nachricht = Payload = Daten als Repräsentation der Ressource Repräsentation = Inhalt oder Teil der Ressource in einem bestimmten Format 7
Methoden der Request Line I Method URL HTTP-Version Methode Definierte/Intendierte Semantik GET HEAD POST PUT Es wird die aktuelle Repräsentation geladen Wie GET, aber nur der Header Operationen werden an der Ressource durchgeführt Die Ressource wird angelegt oder überschrieben DELETE Die Ressource wird gelöscht CONNECT Aufbau einer Verbindung zum Server OPTIONS Holen der Fähigkeiten des Servers TRACE Es wird die Verbindung zum Server getestet 8
Methoden der Request Line II Manchmal wird anstatt von Methoden von Verben gesprochen; es besteht sonst kein Unterschied. Wie später erkennbar wird, reichen für bestimmte Anwendungen die "offiziellen" Methoden nicht aus. Für WebDAV wurden weitere Methoden definiert: u.a. PATCH Siehe: https://tools.ietf.org/pdf/rfc5789.pdf 9
Beispiele für Header-Informationen (Request) Keyword Accept Authorization Cookie Cookie2 Erläuterung Vom Client angeforderte(s) Datenformat(e) "Benutzername:Password" in base64 kodiert Form: Name=Wert Cookie im RFC-2965-Format Als Authentisierung (mit dem Schlüsselwort Authorization) kann die Basic Access Authentication angewendet werden, z.b. konfiguriert über.htaccess-dateien beim Apache-Webserver. 10
HTTP-Response Header Status Line Header Fields Payload MIME-Header Message Kopf = Header = Block von Informationen über die Anforderungen bzw. Antwort Nachricht = Payload = Daten als Repräsentation der Ressource Repräsentation = Inhalt oder Teil der Ressource in einem bestimmten Format 11
http://web-sniffer.net: www.htw-berlin.de I Mit der Site web-sniffer.net können leicht die HTTP-Pakete visualisiert werden. Das geht auch lokal mit Sniffern wie wireshark. 12
http://web-sniffer.net: www.htw-berlin.de II 13
Verbreitung von API-Protokollen (2010) http://www.programmableweb.com/news/ new-job-requirement-experience-building-restful-apis/2010/06/09 14
SOAP/XML vs REST/JSON I SOAP-Version Beispiel aus http://keithba.net/simplicity-and-utility-or-why-soap-lost 15
SOAP/XML vs REST/JSON II REST-Version Beispiel aus http://keithba.net/simplicity-and-utility-or-why-soap-lost 16
Representation State Transfer (REST) - die Idee Client Ressource' Server Ressource Der Client fordert den Zustand einer Ressource an. Per HTTP wird dieser Zustand übertragen und im Client verarbeitet. Im Client und im Server befindet sich dann dieselbe Ressource in verschiedenen Zuständen. Übertragen wird immer die Repräsentation eines Zustands. Daher: Representation State Transfer (REST) 17
Dies stimmt nicht ganz... Es muss nicht (immer) der gesamte Zustand in den Client übertragen werden. Weiterhin setzt eine Ressource eine URI voraus und dies kann nur von einem Client in der Rolle eines Servers realisiert werden. Vereinfachend kann aber von einer Ressource im Klienten gesprochen werden. Dann noch etwas: Klient/Client bedeutet hier eine Maschine in der Rolle des Klienten Server bedeutet hier eine Maschine in der Rolle eines Servers Eine Maschine kann beide Rollen gleichzeitig einnehmen. 18
REST Prinzipien 1) Client-Server-Prinzip Nur vom Client geht der Anstoß einer Aktivität aus (Pull-Prinzip) 2) Zustandslos Der Client liefert alle Informationen mit jedem Request; es gibt im Server keinen Kontext (Sessions) bezogen auf die Kommunikation. 3) Einheitliche Schnittstelle Es werden als Operationen nur die HTTP-Methoden benutzt: GET, PUT, HEADER, POST, DELETE etc. 4) Namen von Ressourcen (URI) Jede Ressource hat eine eigene eindeutige URI. 5) Relationen zwischen Ressourcen durch URI Alle Beziehungen zwischen Ressourcen werden mit Hilfe von URIs ausgedrückt. Schnittstellen, die diesen Prinzipien genügen, werden RESTful genannt. 19
REST - Vorteile 1) Client-Server-Prinzip Verlagerung der Sitzungsinformation in den Client 2) Zustandslos Besseres Skalieren Gute Benutzung von Caches 3) Einheitliche Schnittstelle Einfachheit Theoretisch kann jede Applikation mit jeder anderen zusammenarbeiten 4) Namen von Ressourcen (URI) Universelles Namenskonzept mit eindeutigen Namen 5) Relationen zwischen Ressourcen durch URI Gute Kombinierbarkeit unterschiedlicher Anwendungen 20
Konsequenzen Einheitliche Schnittstelle I Methode Request Response Safe Idempotent Cacheable GET - Body Ja Ja Ja HEAD - - Ja Ja Ja POST Body Body Nein Nein?? PUT Body Body Nein Ja Nein DELETE - Body Nein Ja Nein CONNECT Body Body Nein Nein Nein OPTIONS - Body Ja Ja Nein TRACE - Body Ja Ja Nein Body bedeutet, dass eine Nachricht (Payload) im Paket vorhanden sein kann. Safe bedeutet, dass keine Zustandsänderungen an der Ressource vorgenommen werden. 21
Konsequenzen Einheitliche Schnittstelle II Idempotent = Keine Änderung der Semantik bei ein- oder mehrmaliger Ausführung derselben Operation Duplizierungen durch das Netzwerk verursachen hier keinen Schaden. Nach einem Wiederanlaufen können derartige Operationen jederzeit ausgeführt werden. Cacheable = Der Inhalt des Responses kann in einem Cache für ein späteres GET auf diese Ressource gehalten werden, sei es im Browser oder in einem dem Server vorgeschalteten Cache. Bei der POST-Methode ist das Abspeichern im Cache nicht so klar. Nach einem PUT kann es sinnvoll sein, den Inhalt im Cache zu halten, wenn nämlich durch das PUT der Zustand nicht verändert wurde, z.b. 2x dasselbe PUT auf dieselbe Ressource: dann kann das 2. PUT im Cache gehalten werden. 22
Bemerkungen für RESTful-APIs Die Tabelle gibt die Anforderungen an eine REST-API wieder, d.h. eine API muss diese Eigenschaften realisieren, um RESTful zu sein. In der Praxis gibt es modifizierende Operationen mit der GET- Methode, z.b. GET http://.../objekt?op="delete" Das ist möglich, aber nicht RESTful. Die POST-Operation sollte vermieden werden, da diese keine allgemeinen Eigenschaften definiert. Viele RESTful-APIs sind gar nicht RESTful... 23
Konsequenzen Einheitliche Schnittstelle III Ressource: http://beispiel.de/bestellung/1367 Methode Bedeutung GET PUT Abfrage des Zustands der Bestellung Neuanlegen einer Bestellung oder Ändern einer bestehenden Bestellung DELETE Löschen einer bestehenden Bestellung Es wird das CRUD-Prinzip realisiert: create() mit der PUT-Methode read() mit der GET-Methode update() bzw. write() mit der PUT-Methode delete() mit der DELETE-Methode Mehr Operationen gibt es nicht! Vor allem keine "versteckten" Operationen, wie in GET http://.../objekt?op="delete" 24
Konsequenzen Einheitliche Schnittstelle IV Es werden also nur die Operationen am Objekt (Ressource) selbst angegeben, nicht deren darüber hinaus gehende Bedeutung. Beispiel der Bestellung (Variante 1): Methode Akivität GET PUT PUT Abfrage des Zustands Neuanlegen einer Bestellung Ändern einer bestehenden Bestellung DELETE Löschen Bedeutung Es wird ein Query in einer Datenbank gemacht, die Bestellung und der Bearbeitungsstatus geliefert. Eine Bestellung wird in der Datenbank angelegt und der Prozess der Bearbeitung angestoßen. Ein Teil der Bestellung wird geändert. Die Bestellung wird storniert. 25
Konsequenzen Einheitliche Schnittstelle V Es kann aber auch eine andere Bedeutung definiert werden. Beispiel der Bestellung (Variante 2): Methode Akivität GET PUT PUT Abfrage des Zustands Neuanlegen einer Bestellung Ändern einer bestehenden Bestellung DELETE Löschen Bedeutung Es wird ein Query in einer Datenbank gemacht und die Bestellung geliefert. Eine Bestellung wird in der Datenbank angelegt und der Prozess der Bearbeitung angestoßen. Dies wird abgelehnt. Die Bestellung wird archiviert. 26
Bemerkungen zum Stil Prozeduraler/Objekt-Orientierter Stil: Die unterschiedliche Semantik drückt sich durch unterschiedliche, differenzierte Namen der Operationen primär im Server aus, der die Semantik realisiert. Es gibt RPCs. REST-Stil: Die Semantik der Anwendung ist implizit; die HTTP-Methode beschreibt nicht das, was sie eigentlich tut, sondern bezieht sich auf die Änderung von Zuständen. Die Operation wird primär im Client ausgeführt. Es gibt keine RPCs, sondern nur eine Übertragung von fertig erstellten Zuständen. 27
Dies stimmt nicht ganz... So betrachtet würde der Server nur die Funktion des Abspeicherns und Lieferns von Ressourcen haben. Für statische Web-Seiten ist das vollkommen in Ordnung, aber für "richtige" Anwendungen nicht, denn es wird Kontext benötigt: Prüfung der Identität (Authentisierung) Prüfung von Autorisierungen (Single Sign On, SSO) Realisierung von Transaktionen... Auf diesen Kontext muss der Server zugreifen können. Damit die API RESTful wird, muss der Kontext selbst wiederum eine Ressource sein, deren URI der Client kennen muss, aber keinen Zugriff haben sollte bzw. darf. Um aber die Erlaubnis zum Zugriff auf die Kontext-Ressource prüfen zu können, ist eine kleine Session-Information nötig. 28
In der Praxis... wird häufig "geschummelt": Es werden Zusatzinformationen über die Operation beim Request mitgegeben oder sogar ganz offen ein RPC mit der PUT-Operation verbunden. Gründe: Bei den schreibenden Operationen gibt es häufig mehrere Möglichkeiten, aus denen durch Zusatz-Informationen gewählt wird. Diese gehen über ein PUT weit hinaus. Software-technisch hier vom Aspekt der Wartung her ist das reine REST eine Katastrophe, weil nicht die Semantik in der API ausgedrückt wird. Dies führt zu schwer verständlichen Code. 29
Namenswahl I Die Ressourcen sollten mit Substantiven bezeichnet werden, nicht mit Verben. Beispiele Modifizieren: PUT http://.../object/12345 Nicht: PUT http://.../object/12345?op=mod Nicht: PUT http://.../object/12345/mod Löschen: DELETE http://.../object/12345 Nicht: PUT http://.../object/12345?op=delete Nicht: PUT http://.../object/12345/delete Das folgende Beispiel ist eine Katastrophe: GET http://.../object/12345/delete falsch falsch falsch denn der Crawler von Google würde die Ressource löschen Jedenfalls wenn er die Erlaubnis dazu hätte. 30
Namenswahl II - Templates URI-Template = Schablone zum Aufbau von URIs mit variablen Bereichen Beispiele http://...de/{name} http://...de/orders http://...de/persons http://...de/{name}/{id} http://...de/orders/1289 http://...de/persons/465 Der Name in {} ist eine Variable, die durch aktuelle Werte ersetzt wird. Siehe: http://tools.ietf.org/pdf/rfc6570.pdf https://de.wikipedia.org/wiki/url-template 31
Dateisysteme sind ein bisschen RESTful Alle Dateien haben einen (einheitlich aufgebauten) Namen, z.b. /etc/ntp.conf Auf allen Dateien gibt es nur einen festen Satz von Operationen: Z.B. UNIX: open() read() write() seek() close() Auch die Permissions sind einheitlich: read, write Execute für Owner, Group und World Aber was die Operationen wirklich bedeuten, ist dem Betriebssystem unbekannt. 32
Arten von Ressourcen I Ressourcen oder Primärressourcen Typische URI: http://...de/{name}/{id} Subressourcen als Teil anderer Ressourcen Typische URI: http://...de/{name}/{id}/{name}/{id} Beispiele Bestandteile eines Dokuments Liste der Gegenstände einer Bestellung Listenressourcen als Zusammenfassung anderer Ressourcen Typische URI: http://...de/{name} Filter (Auszüge aus Listen) Typische URI: http://...de/{name}?q={bedingung} Paginierung (Aufteilen von Listen) Typische URI: http://...de/{name}?page={nummer} 33
Arten von Ressourcen II Projektionen Ressource, die aus Teilen einer anderen besteht Aggregationen Zusammenfassung von Teilen verschiedener Ressourcen Aus der Sicht von REST besteht eine URI einer Ressource aus dem gesamten String der URI unabhängig vom Aufbau. Das? in der URI wird also nicht besonders beachtet. 34
Realisierung von Ressourcen Eine Ressource kann als Datei realisiert werden. Dies ist der Normalfall im Web., z.b. http://...de/logo.jpg Die Dateitypenangaben (.jpg,.png,.html etc.) werden häufig weggelassen; dann aber müssen die URIs im Request durch den Server umgeschrieben werden, so dass intern wieder mit Endungen gearbeitet wird. Eine Ressource kann aber auch durch Zeilen in Tabellen einer relationalen Datenbank realisiert werden. Dann muss durch Umschreiben der URI der Code zum Zugriff auf die Datenbank angesprochen werden. Das geht natürlich auch mit NoSQL-Datenbanken. Siehe: http://www.modrewrite.de/ https://de.wikipedia.org/wiki/rewrite-engine 35
Verknüpfung von Ressourcen I {..., "links":{ }... Symbolischer Name URI dazu "all": "http://...de/workers", "employees": "http://...de/workers?q=employees", "dismissed": "http://...de/workers?q=dismissed", "retired": "http://...de/workers?q=retired" }, Verknüpfungen erfolgen grundsätzlich über URIs. Verknüpfungen können symbolisch benannt werden, um durch den höheren Abstraktionsgrad Unabhängigkeit zu erreichen. Im Client werden die symbolischen Bezeichnungen zu URIs gemacht und benutzt. 36
Verknüpfung von Ressourcen II {..., "links":{ "person": "http://...de/persons?q={id}", "file": "http://...de/files?q={id}", "note": "http://...de/notes?q={id}", "finished": "http://...de/steps?q={id}&s=finished" },... } Listenressourcen können andere unter einem Aspekt zusammen fassen, z.b. Vorgänge in der Verwaltung bzw. im Workflow Management. Wenn in URIs Templates verwendet werden, so muss dies dem Client mitgeteilt werden bzw. von der API her vorgesehen sein. Am besten sind "sich selbstbeschreibende" Ressourcen, die also explizit angeben, ob die URIs Templates sind. 37
Verknüpfung von Ressourcen III {..., "links":{ "create": "http://...de/files?q={id}", "deactivate":"http://...de/files?q={id}&s=deactivate", "rename": "http://...de/files?q={id}&s=rename", "archive": "http://...de/files?q={id}&s=archive" },... } Es sind auch Verzeichnisse von Operationen möglich. Dabei muss die Methode hier im Beispiel immer PUT klar sein. Dasselbe gilt auch für die Formate der JSON-Informationen, die dem PUT mitgegeben werden müssen. Dies ist aber eigentlich nicht RESTful. 38
Definition der Schnittstellen I Da bei REST sehr viele Information implizit sind, sollte die API syntaktisch vollständig als Ressource selbst definiert sein. Denn dann kann ein beliebiger Klient die Schnittstelle syntaktisch korrekt bedienen. Semantisch sieht es anders aus. Verfahren: 1)Der Klient holt sich die API-Definitions-Ressource 2)Anhand eines standardisierten Katalogs wird die Operation samt URI bestimmt. 3)Parameterliste bzw. Formate der Ressourcen werden gelesen, 4)entsprechend werden die Requests konstruiert, 5)und entsprechend werden die Responses interpretiert. 39
Definition der Schnittstellen II - Definitionen Beispiele für API-Definitionssprachen: Hypertext Application Language (HAL) basierend auf JSON http://stateless.co/hal_specification.html https://apigility.org/documentation/api-primer/halprimer https://en.wikipedia.org/wiki/hypertext_application_language RAML basierend auf YAML http://raml.org https://en.wikipedia.org/wiki/raml_(software) Zu YAML: http://www.yaml.org/ SIREN basierend auf JSON https://github.com/kevinswiber/siren https://gist.github.com/kevinswiber/3066768 40
Versionen von Schnittstellen I Schnittstellen sollten konstant und langlebig sein. Dies gilt besonders für REST, da im Falle einer Änderung der API sehr viele Referenzen vor allem in den Ressourcen geändert werden müssen. Der nachhaltige Entwurf von APIs aber nicht einfach. Er ist genau das Gegenteil zu agilen Techniken. Siehe https://de.wikipedia.org/wiki/nachhaltigkeit https://de.wikipedia.org/wiki/nachhaltige_entwicklung Pragmatisch wird eine Versionsnummer in die URIs eingebaut: http://domain.top/version/identifier? XXX=YYY... Z.B. v1 in http://...de/v1/orders/12345 41
Versionen von Schnittstellen II Die Frage ist, wann alte Schnittstellen entfernt werden können. Eigentlich nie... Also: Der Entwurf von REST-APIs ist immer langfristig auszurichten. 42
Nach dieser Anstrengung etwas Entspannung... 43