RESTful Webservices

Das Schaubild eines RESTful Webservices

Neben den bekannten WS-* Stack (SOAP, WSDL, WS-* Universum) gibt es noch weitere Möglichkeiten einen Webservice zu implementieren. Dieses ist zum Beispiel der Architekturstil REST (REpresentational State Transfer). Dieser Beitrag führt in die maßgeblichen Prinzipien der RESTful Webservices ein.

Der Architekturstil REST

Die REST Architektur wurde von Roy Thomas Fielding im Jahr 2000 in seiner Dissertation als ein Architekturstil für verteilte Hypermedia Systeme formuliert. Roy Fielding ist einer der Hauptautoren der Spezifikation des Hypertext-Transfer Protokolls (HTTP/1.1). Die REST Architektur nutzt das HTTP-Protokoll vollständig – im Gegensatz zu den Webservices des WS-* Stacks, die ein SOAP over HTTP Protokoll (XML basierend) einsetzen und das unterliegende HTTP Protokoll nur rudimentär benutzen.

Die RESTful Webservices

Der Architekturstil REST wird bei der Integration oder der Kommunikation zwischen Anwendungen verwendet. Der Aufruf eines RESTful Webservices wird nicht durch einen Anwender in einem Browser ausgelöst. Obwohl es bei einem information-lieferndem Webservice per HTTP GET durchaus vorstellbar ist, die Daten als eine HTML-Seite zu präsentieren. Allerdings könnten aus einer Webanwendung heraus AJAX (Asynchronous JavaScript and XML) Aufruf gegen einen RESTful Webservice erfolgen.

Die RESTful Webservices sind Statuslos und liefern die Daten in unterschiedliche Repräsentationen (Formate) an den Aufrufer. Die Daten werden in mit einer URI eindeutig identifiziert und als Ressource bezeichnet. Durch den statuslosen Zustand der Kommunikation können alle Caching Mechanismen von HTTP-Servern (Gültigkeitszeitraum, Validieren, ETag, etc.) verwendet werden. Das ist ein wesentliches Element des REST Architekturstils.

Ressourcen und ihre Repräsentationen

Was ist eine Ressource?

Eine Ressource ist eine semantische Entität und wird über eine langlebige URI (Uniform Resource Identifier, RFC 3986 – Uniform Resource Identifier (URI)) identifiziert bzw. adressiert. Sie kann eine oder mehrere Repräsentationen (z. B. XML, JSON, PDF, HTML, ATOM, RSS/RDF, etc.) besitzen.

Ein Beispiel ist die Abfrage einer Adresse oder Person, die als vCard (elektronische Visitenkarte, application/vcard, RFC 2426) geliefert wird.

Wie wird eine Ressource identifiziert?

Die ID einer Ressource, die URI, sagt nicht über die Verwendung oder eine Veränderung der Ressource aus. In der URI ist keine Informationen enthalten, die Auskunft darüber gibt, was mit der Ressource geschehen soll.

Eine URI dient genau zur Identifizierung einer Ressource.

Durch die erste URI wird der Kunden mit der Kundennummer 4711 und mit der letzten URI das Produkt mit der Produktnummer 1 identifiziert. In der Mitte wird der Fahrer A33 identifiziert.

Eine URI sollte nicht mit einem Schrägstrich  / enden. Dieses zusätzliche Zeichen fügt der URI keinen semantischen Wert hinzu und kann weggelassen werden.

Dabei können die eindeutigen Schlüssel der Datenbank ein Teil der URI sein. Allerdings sollte einer Ressource keine direkte Entität aus der Datenbank entsprechen. Sondern aus einem serviceorientierten Entwurfes hervorgehen.

Die folgende URI ist ungültig, falls sie keine einzelne Ressource identifiziert, sondern eine Menge von Ressourcen.

Die folgende URI ist gültig, wenn sie eine Liste von Ressource identifiziert und die URI die Liste als Ressource referenziert.

Der hierarchische Aufbau einer URI ist nicht notwendig. Eine URI muss im Wesentlichen eine Ressource eindeutig identifizieren, dieses kann durchaus kryptisch erfolgen.

In einer URI können Bindestriche  - verwendet werden, um die Lesbarkeit von URIs zu verbessern.

Von Unterstrichen  _ sollte in der URI, wegen der Unterstreichung von URLs in der Darstellung von Browsern, abgesehen werden.

Um Verwechselung von URIs zu vermeiden, sollte keine Großschreibung verwendet werden. Das Protokoll und der Hostname in einer URL dürfen großgeschrieben werden – während beim Pfad zwischen Groß- und Kleinschreibung unterschieden wird.

Was sind verschachtelte Ressourcen?

Die Ressourcen können verschachtelt (nested resources) werden. Die verschachtelten Ressourcen sind eng gekoppelte Ressourcen im Sinne von Eltern-Kind-Beziehung (1:N). Die Kinder sind an ihren Eltern gebunden, so dass ihre Verwendung ohne Eltern keinen Sinn macht.

Die Verschachtlung oder Hierarchie der Ressourcen, wird in der URI mit einem Schrägstrich  / ausgedrückt.

In diesem Beispiel wurde die Bestellung mit der Nummer 1 des Kunden mit der ID 4711 referenziert.

Die Content Negotiation

Mehrere alternative Repräsentationen werden durch die Content Negotiation zu Verfügung gestellt.

Die Antwort einer REST Anfrage kann auf unterschiedlichen Content Anforderungen reagieren. Dazu wird das HTTP-Header Feld Accept: text/plain ausgewertet und die Repräsentation in gewünschten Format in der Antwort (HTTP-Header Feld Content-Type: test/plain) berücksichtigt werden. Allerdings ist zu Beachten, dass diese Anforderung als ein Wunsch betrachtet wird und die Antwort anders aussehen kann.

Ein detailliertes Beispiel ist im Beitrag Content Negotiation zu finden.

Hypermedia (Verlinkung)

Unter REST werden die Verweise (Links) auf andere Ressourcen mit URIs dargestellt. Diese Verweise werden auch mit Hyperlinks, Hypermedia, Verlinkung oder Verknüpfung bezeichnet.

Mit diesen URIs kann direkt zwischen den Ressourcen navigiert werden. Zusätzlich können z. B. Distributed Caching realisiert werden, welche erst durch die URIs und die Hyperlinks möglich sind.

Diese Beschreibung von Services kann auch im HTTP Header (Web Linking) platziert werden.

Wobei diese Möglichkeit meistens bei Navigation bei Listen angewendet wird.

Gleichförmige (uniforme) Schnittstellen

Der Architekturstile REST vereinheitlicht (uniforme) die Schnittstellen der Ressourcen auf eine überschaubare und – bezüglich des zu erwartenden Verhaltens – standardisierte Menge von Aktionen.

Diese Aktionen sind Teil des Anwendungsprotokolls HTTP/1.1 bzw. HTTPS (RFC 2616).

HTTP Methoden

Zur Zeit werden im Internet nur die HTTP Methoden GET und POST genutzt, da nur sie von den Browsern unterstützt werden.

Aber es gibt noch weitere HTTP Methoden, wie z. B. PUT und DELETE, die in einer REST Architektur verwendet werden können. Diese HTTP Methoden werden auch Verben oder Operationen genannt.

Die Eigenschaften von HTTP Methoden

  • safe
    Der Aufruf dieser Operation hat keine Nebenwirkungen, d. h. die Ressource erfährt durch den Abruf keine Änderung. Das heißt aber nicht, dass der Webservice intern eine Zustandsänderung vorgenommen hat. Dieses können Logeinträge oder das Fortschreiben von statistischen Aufzeichnungen sein. Wichtig aus Sicht des Architekturstils REST ist es, dass für den Aufrufer die Ressource sich nicht geändert hat.
  • idempotent
    Das mehrfache Aufrufen dieser Operation liefert immer das gleiche Ergebnis.
    Mathematisch: ƒ(ƒ(x)) = ƒ ∘ ƒ(x) = ƒ(x) 😉
    Wenn nun der Aufrufer keine Antwort auf eine Anfrage erhalten hat, kann er diese Anfrage bei idempotenten Operationen einfach wiederholen. Er muss nicht prüfen, ob die Operation schon verarbeitet worden ist, das muss er nur bei nicht idempotenten Operationen.

HTTP Methode GET

Die Anforderung einer Ressource, die durch eine URI identifiziert wird, ohne das die Ressource dadurch eine Veränderung erfährt. Der Webservice liefert die Repräsentation einer Ressource.

Diese HTTP Methode GET ist safe und idempotent.

Querys dürfen nur verwendet werden, wenn das Ergebnis eine eindeutige identifizierte Ressource ist.

Dieses ist meistens der Fall, wenn das Ergebnis selbst als Ressource gewertet wird, z. B. eine Liste von Ressourcen oder das Ergebnis einer Berechnung unter der Beachtung der Eigenschaften safe und idempotent.

Der folgende Aufruf ist nicht zulässig, da dieser Aufruf nicht safe und nicht idempotent ist. Wird diese Anfrage wiederholt an einen Webservice gesendet, so unterscheiden sich im folgenden Beispiel die Antworten.

Durch die Eigenschaften safe und idempotent können Bookmarks bzw. Caches relativ einfach aufgebaut werden, da der wiederholte Aufruf keinen Schaden anrichten kann. Die Verantwortung dazu liegt nicht bei Aufrufer, sondern ausschließlich beim Provider.

HTTP Methode PUT

Die Anfrage der HTTP Methode PUT aktualisiert die bestehende identifizierte Ressource mit den angehängten Daten. Sollte die Ressource noch nicht existieren, wird sie unter der angegebenen URI mit den angehängten Daten angelegt.

Die Daten werden in einer gültigen Repräsentation der Ressource gesendet.

Die HTTP Methode PUT ist idempotent.

HTTP Methode DELETE

Das Löschen bzw. das Entfernen der identifizierten Ressource. Falls die Ressource nicht existiert, wird kein Fehler ausgelöst, da das gewünschte Ergebnis schon erreicht ist.

Nach dem Verarbeiten der HTTP Methode DELETE liefert die HTTP Methode GET ein HTTP/1.1 404 Not Found.

Ob die Ressource tatsächlich aus der Datenbank gelöscht oder nur als gelöscht bzw. storniert markiert wurde, liegt in der Verantwortung des Webservices bzw. der zugrundeliegenden Fachlichkeit. Die Ressource darf nur nicht mehr unter der ursprünglichen URI geliefert werden.

Die HTTP Methode DELETE ist idempotent.

Das mehrfache Löschen darf keinen Fehler liefern und die Ressource darf von außen nicht mehr erreicht werden.

HTTP Methode POST

Eine oder mehrere Ressourcen erzeugen, deren URIs noch nicht bekannt sind bzw. eine unbestimmte Menge von Ressourcen ändern oder löschen. Die zugehörigen Daten hängen der Anfrage an. Durch die folgende Anfrage wird eine neue Ressource erzeugt und die identifizierende URI in der Antwort per Location Attribut zurückgegeben.

Diese HTTP Methode POST bietet die meiste Flexibilität und kann bzw. darf Seiteneffekte haben, da sie weder safe noch idempotent ist.

Der Absender hat eine gewisse Verantwortung, da die HTTP Methode POST keine Garantien liefert. Der Absender sollte also wissen, was er anstellt.

HTTP Methode HEAD

Die HTTP Methode HEAD fragt den HTTP-Header zu der identifizierten Ressource ab. Diese Anfrage liefert den gleichen Header, wie die HTTP Methode GET, nur ohne Daten.

Die HTTP Methode HEAD ist safe und idempotent.

HTTP Methode OPTIONS

Die HTTP Methode OPTIONS prüfen, welche HTTP Methoden auf der identifizierten Ressource zur Verfügung stehen.

Die HTTP Methode OPTIONS ist idempotent.

HTTP Methode TRACE

Die HTTP Methode TRACE liefert die Anfrage so zurück, wie der Server sie empfangen hat. So kann überprüft werden, ob und wie die Anfrage auf dem Weg zum Server verändert worden ist.

HTTP Methode CONNECT

Diese HTTP Methode CONNECT wird von Proxyservern implementiert, die in der Lage sind, SSL Tunnel zur Verfügung zu stellen.

HTTP Statuscodes

Die Antwort eines RESTful Webservices beinhaltet einen HTTP Statuscode und ggf. die angeforderte Ressource.

HTTP Statuscodes 2xx

Mit einem HTTP Statuscode aus der 200-Gruppe wird ein Erfolg signalisiert.

  • 200 OK
    Signalisiert den Erfolg eines Zugriffes oder Änderung.
  • 201 Created
    Bestätigt das Anlegen einer Ressource.
  • 204 No Content
    Bestätigt eine Änderung, liefert aber keine Daten zurück.

HTTP Statuscodes 3xx

Die HTTP Statuscode aus der 300-Gruppe leiten die Bearbeitung an den aufrufenden Client zurück.

  • 303 See Other
    Verweis auf eine andere Ressource unter der URI aus dem HTTP-Attribut Location.

HTTP Statuscodes 4xx

Mit einem HTTP Statuscode aus der 400-Gruppe signalisiert der Webservice, dass er die Anfrage nicht interpretieren oder durchführen konnte. Wobei der Fehler eher durch den aufrufenden Client ausgelöst wurde.

  • 409 Conflict
    Die Anfrage wurde unter falschen Annahmen gestellt (Bei PUT: Die Ressource wurde zwischenzeitlich geändert).
  • 410 Gone
    Die Ressource war unter der URI zu finden, wird aber nicht mehr bereitgestellt.
  • 412 Precondition Failed
    Eine in der Anfrage übertragene Voraussetzung wurde nicht erfüllt.
  • 415 Unsupported Media Type
    Der Content einer Anfrage wurde mit einem nicht erlaubten Inhalt übertragen.
  • 422 Unprocessable Entity
    Der Content der Anfrage konnte nicht verarbeitet werden, z. B. durch semantische Fehler.

HTTP Statuscodes 5xx

Ein HTTP Statuscode aus der 500-Gruppe zeigt einen Fehler im Service an.

  • 500 Internal Server Error
    Ein allgemeiner Fehler im Webservice oder Server ist aufgetreten.

Die Beschreibungen der restlichen Statuscodes gibt es bei der Wikipedia.

Content Negotiation

Die Antwort auf eine REST Anfrage kann unterschiedliche Repräsentationen bzw. Content Formate liefern. Dazu wird das HTTP-Header-Feld Accept ausgewertet und aus dieser Wunschliste eine Repräsentation für die Antwort (HTTP-Header-Feld: Content-Type) ausgewählt. Diesen Vorgang wird Content Negotiation genannt. Hier entscheidet letztendlich der RESTful Webservice, welche Repräsentation er liefert.

Dabei stehen alle möglichen MIME-Typen zu Verfügung ( text/plain, text/html, text/xml, text/rdf, text/rss, text/x-vcard, application/xml, application/json, application/pdf, …).

In der Form application/vnd.frankrahn.drivers+xml kann auf einen nicht standardisierten XML MIME-Typ verwiesen werden.

Syntax := "application/vnd.", Hersteller, ".", XML-Schema, "+xml";

Im folgenden Beispiel kann eine XML- oder eine HTML-Repräsentation in der Antwort geliefert werden, dabei ist die XML-Repräsentation höher priorisiert ( q=1.0) und die Version ( schemaVerion=1.1) des zu verwendenden XML-Schemas festgelegt.

Der RESTful Webservice liefert die angeforderte Ressource als XML-Repräsentation.

Mit der folgenden Antwort zeigt der RESTful Webservice an, dass er die Ressource nicht in einer der gewünschten Repräsentationen liefern kann.

Distributed Caching (Validation/Expiry)

Um die Effizienz von Anwendungen zu steigern, werden häufig Caches eingesetzt. Bei einer REST Architektur können die Ressourcen mit etablierten Verfahren des Anwendungsprotokolls HTTP gecacht werden.

Dazu bietet das HTTP-Protokoll einige Attribute im Zusammenhang mit dem Distributed Caching an:

  • Last-Modified: Zeitstempel
    Wird vom Webservice in der Antwort geliefert und ermöglicht das Caching erst.
  • If-Modified-Since: Zeitstempel
    Wird bei einer erneuten Anfrage gesetzt und nur falls die Ressource nach diesem Datum verändert worden ist, wird sie auch gesendet.
  • ETag: "Entity-Tag"
    Wird vom Webservice mit der Antwort geliefert.
  • If-None-Match: "Entity-Tag"
    Wird bei einer erneuten Anfrage gesetzt und falls der aktuelle Entity-Tag der Ressource nicht passt, wird sie gesendet.

Im folgenden Beispiel wird eine Ressource abgefragt …

… und auch erfolgreich geliefert.

In einer spätereren Abfrage der gleichen Ressource wird das HTTP Attribut If-Modified-Since mitgeliefert …

… und die Antwort liefert die angeforderte Ressource nicht mehr, da sie aktuell ist.

Dieses Verfahren wird erst durch die Eigenschaften safe und idempotent der HTTP Methode GET ermöglicht, da der Abruf einer Ressource, die Ressource selber, nicht verändern darf.

Asynchrone Kommunikation

Standardmäßig ist die Kommunikation mit dem HTTP Protokoll durch den Ablauf des Request/Response Zyklus synchronisiert. Allerdings kann durch den HTTP Statuscode HTTP/1.1 202 Accepted und der Rückgabe einer URI im HTTP Attribut Location für das Ergebnis eine asynchrone Kommunikation aufgebaut werden.

Der HTTP Statuscode besagt, dass die Anfrage zu einem späteren Zeitpunkt bearbeitet wird und unter der angegebenen URI abgeholt werden kann.

Die Antwort enthält einen Verweis auf die erzeugte Ressource.

Die erfolgreiche Ausführung des Webservices wird allerdings nicht garantiert. Eine vorschnelle Abfrage GET https://www.frank-rahn.de/drivers/4712 HTTP/1.1 würde ein HTTP/1.1 404 Not Found liefern.

Reliable Messaging

Wenn eine Anfrage an einen Service-Provider gesendet wird, aber nie eine Antwort zurückkommt, kann man sich nicht sicher sein, dass die Anfrage tatsächlich angekommen ist. Eine Lösung kann durch das wiederholte Senden erreicht werden. Dieses kann bei idempotenten HTTP Methoden ohne Bedenken durchgeführt werden. Aber bei den HTTP Methoden, die nicht idempotent sind, müssen zusätzliche Mechanismen (z. B. Message-Id, Zeitstempel, …) angewendet werden, so dass der Service-Provider doppelte Anfragen erkennen kann.

Cookies

Als Cookies werden Textinformationen bezeichnet, die von Webserver auf dem Computer des Benutzers über den Browser beständig gespeichert werden. Darin werden z. B. Passwörter und Angaben über den aktuellen Benutzer abgelegt. In einer späteren Sitzung werden die Cookies direkt an den Webserver gesendet.

Die Cookies sind in einer REST Architektur nur zulässig, wenn sie allgemeine Informationen, wie z. B. Tokens, Tickets oder Session-Ids, bei Aufrufe von Webservices transportieren.

Redirection, Compression, Chunking

Diese HTTP Eigenschaften (Umleitungen, Komprimierung und Stückelung von Nachrichten) werden noch beschrieben.

Beispiele von RESTful Webservice Schnittstellen

Die Schnittstellen eines RESTful Webservices müssen formal definiert werden. Dieses kann beispielsweise über eine WSDL, ein XML Schema (XSD) oder eine beliebige Beschreibungssprache erfolgen.

Im folgenden Beispiel wird die RESTful Webservice Schnittstelle einer Kundenverwaltung dargestellt. Ein weiteres Beispiel ist der Beitrag Spring mit RESTful Webservice.

Schnittstelle zu den Kunden
URI /customers
POST Erzeuge einen neuen Kunden.
GET Listet alle Kunden auf.
Query-Parameters:

  • state=open-orders
    Liefere die Kunden mit offene Bestellungen.
  • page={Nummer}
    Dieser Parameter segmentiert die Ausgaben.
PUT
DELETE
HEAD Liefere die Anzahl aller Kunden.
Schnittstelle zu einem bestimmten Kunden
URI /customers/{Kundennummer}
POST
GET Liefere den Kunden mit der Kundennummer.
PUT Ändere den Kunden mit der Kundennummer.
DELETE Lösche den Kunden mit der Kundennummer.
HEAD
Schnittstelle zu den Bestellungen eines bestimmten Kunden
URI /customers/{Kundennummer}/orders
POST Erzeuge eine neue Bestellung des Kunden mit der Kundennummer.
GET Listet alle Bestellungen des Kunden mit der Kundennummer auf.
PUT
DELETE Lösche alle Bestellungen des Kunden mit der Kundennummer.
HEAD Liefere die Anzahl aller Bestellungen des Kunden mit der Kundennummer.
Schnittstelle zu einer einzelnen Bestellung eines bestimmten Kunden
URI /customers/{Kundennummer}/orders/{Bestellungsnummer}
/orders/{Bestellungsnummer}
POST
GET Liefere die Bestellung des Kunden.
PUT Ändere die Bestellung des Kunden.
DELETE Lösche die Bestellung des Kunden.
HEAD
Schnittstelle zu einer speziellen Bestellung eines Kunden
URI /customers/{Kundennummer}/orders/date/{Bestellungsdatum}
POST
GET Liefere die Bestellungen des Kunden mit dem Datum.
PUT
DELETE
HEAD

Unter dem Link URI Templates finden Sie eine Beschreibung, wie URIs mit Variablen zu definieren sind.

Zustandslose Kommunikation

Die Kommunikation mit einem RESTful Webservice erfolgt immer zustandslos, d. h. der Server verwaltet keinen Kontext über die Interaktion mit einem Aufrufer. Dadurch ergeben sich erhebliche Vorteile für die Skalierung und Ausfallsicherheit solcher Systeme, da diese Systeme auf mehrere Server verteilt werden können. Es können auch zusätzliche Dienste, wie HTTP-Proxies oder Browser-Cache, für die Steigerung der Performanz dazwischen geschaltet werden.

Es wird zwischen den zwei Zuständen Anwendungs- und Ressourcenzustand unterschieden.

Der komplexe Anwendungszustand existiert nur auf dem Client. Durch eine Repräsentation einer Ressource wird der Client in einen Anwendungszustand versetzt.

Der Zustand der Ressource wird ausschließlich auf dem Server verwaltet. Es erfolgt kein Abgleich zwischen den Zuständen. Der Server verwaltet keine speziellen Daten (z. B. im Session-Kontext per Cookies) zu einem Client. Dieser muss bei einer Anfrage alle notwendigen Daten mitgeben oder die Daten (z. B. ein Warenkorb) werden in einer eigenen (temporären?) Ressourcen zwischen gespeichert.

Somit kann ein Server zwischen zwei Aufrufen durch gestartet werden, ohne dass dieses eine Auswirkung hat oder eine Behinderung darstellt.

Die Literaturempfehlung

Frank Rahn

Frank Rahn ist Softwarearchitekt. Er unterstützt bei der Konzeption von Softwarearchitekturen mit Java-Technologie. Folge Sie ihm auf Facebook, Twitter oder Google+.

Benötigen Sie Unterstützung? Kontaktieren Sie ihn.

Hat Ihnen dieser Beitrag gefallen? Wir würden uns über Ihren Kommentar freuen! Bitte verwenden Sie Ihren bürgerlichen Namen und eine E-Mail-Adresse mit Gravatar.

Letzte Artikel von Frank Rahn (Alle anzeigen)

1 Antwort

Dein Kommentar

Want to join the discussion?
Feel free to contribute!

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.