REST

REST steht für REpresentational State Transfer und bezeichnet einen Architekturstil (oder auch „Programmierparadigma für verteilte Systeme“, siehe dazu auch Wikipedia), der bereits häufig benutzte Techniken und Protokolle zusammenfasst und für die Datenübertragung nutzt. Dies umfasst:

  • URI für die Adressierung von Ressourcen
  • HTTP für Übertragung von Kommandos
  • MIME für die Kodierung der Ressourcen
  • JSON und XML für die Formatierung

I> ### Webdienst
I> REST ist eine spezielle Form eines Webdienstes (web service). Man spricht deshalb auch von einem REST-Dienst.

Merkmale

Die technischen Merkmale eines REST-Dienstes sind:

  • Adressierbarkeit
  • Repräsentationsvariabel
  • Zustandslosigkeit
  • Skalierbarkeit
  • Allgemeingültig
  • Erweiterbar

Adressierbarkeit

Jeder REST-konforme Dienst hat eine eindeutige Adresse, den Uniform Resource Locator (URL). Zusätzlich zum URL, der den Dienst selbst adressiert, verwendet REST auch Uniform Resource Identifier (URI), um einzelne Ressourcen zu bezeichnen.

Repräsentationsvariabel

Die unter einer Adresse zugänglichen Dienste können unterschiedliche Darstellungsformen (Repräsentationen) haben. Ein REST-konformer Server kann z.B. HTML, JSON oder XML liefern. Dies können Daten oder Beschreibungen von Daten sein.

Zustandslosigkeit

Jede REST-Nachricht enthält alle Informationen, die für den Server bzw. Client notwendig sind, um die Nachricht zu verstehen. Weder der Server noch die Anwendung soll Zustandsinformationen zwischen zwei Nachrichten speichern. Man spricht daher von einem zustandslosen (stateless) Protokoll. Jede Anfrage eines Clients beinhaltet sämtliche Informationen über den Anwendungszustand, die vom Server benötigt werden.

Skalierbarkeit

Die Zustandslosigkeit begünstigt die Skalierbarkeit eines Dienstes. Da jede Anfrage zu einer definierten Reaktion führt und keine Voraussetzungen auf einer bestimmten Maschine vorhanhden sein müssen, können Lastverteiler Anfragen auf mehrere Maschinen verteilen, ohen dass dies Änderungen an der serverseitigen Verarbeitung nach sich zieht.

Allgemeingültig

HTTP schreibt vor, dass GET „sicher“ (safe) sein muss. Dies bedeutet, dass diese Methode nur Informationen beschafft und keine Nebeneffekte hat. Die Methoden GET, HEAD, PUT und DELETE müssen idempotent sein, was bedeutet, dass das mehrfache Absenden der gleichen Anforderung sich nicht anders auswirkt als ein einzelner Aufruf.

Erweiterbar

Erweiterbarkeit heißt, das später erfolgende Erweiterungen der Ressourcenbasis, zusätzliche Funktionen, mehr Daten, anderen Repräsentationen oder Skalierungsmaßnahmen sich nicht auf die bestehenden Clients auswirken dürfen.

Beispiel

Ein Merkmal von REST ist die Beschreibung von Ressourcen. Dazu gehören Links zu weiterführenden Elementen. Bestehen zwischen Daten Beziehungen, so ist dies in der Antwort zu erkennen. Eine einfach Abfrage nutzt das Kommando GET (siehe auch Abschnitt zu HTTP weiter unten).

GET /book/2605
HTTP/1.1 200 OK Content-Type: text/xml
<?xml version="1.0"?>
<book xmlns:xlink="http://www.w3.org/1999/xlink">
    <cat xlink:href="http://shop.texxtoor.de/cat/122">122</cat>
    <author xlink:href="http://shop.texxtoor.de/author/1">1</author>
    <author xlink:href="http://shop.texxtoor.de/author/2">2</author>
    <title>JADE</title>
    <desc>Die Template-Engine JADE</desc>
    <price>2,99</price>
    <type>Paperback</type>
</book>

Hier verweisen die URIs einiger Elemente auf abhängige Ressourcen. Der Client kann dies nutzen, um einen Teil der Benutzeroberfläche dynamisch zu erstellen.

URI

URI steht für Uniform Resource Identifier und ist das Verfahren zum Konstruieren der Adressen. Im Zusammenhang mit REST ist oft der Begriff RESTful zu sehen. Es ist wichtig zu verstehen, dass damit die korrekte Implementierung von REST gemeint ist. Das heißt nicht, das lediglich HTTP benutzt wird, sondern auch, dass die Routen, die zum Abruf von Daten und zum Auslösen von Aktionen benutzt werden, bestimmten Kriterien gehorchen.

URI wird oft mit URL (Uniform Resource Locater) verwechselt. URL ist eine Spezialform des URI. URLs dienen der Adressierung von Webseiten im Browser. URIs können dies und noch einiges andere adressieren. In URLs werden zum Anhängen von Daten Parameter benutzt, die durch ein ?Zeichen abgetrennt sind. Diesen Teil nennt man Querystring. Folgendes sind typische Anwendungsfälle:

  • /admin/updatebook.aspx?book=2605
  • /bookview.html?book=2605
  • /bookreviews.py?book=2605

Der Teil book=2605 ist der Querystring. Dies ist nicht RESTful. RESTful verlangt, dass der Datenteil als Teil der URL erfasst wird. Routen — das sind Adressierungsschemata auf Basis von URIs — haben definierte Abschnitte, denen eine Bedeutung zugewiesen wird. Diese Zuweisung ist willkürlich (Sache des Entwicklers), läuft aber häufig nach einem einfachen Prinzip:

/ressource/id

Oder etwas komplexer:

/ressource/id/aktion

RESTful würden die Beispiele eben wie folgt aussehen:

  • /admin/book/2605
  • /book/2605
  • /book/2605/view

Freilich sind hier immer noch viele Optionen vorhanden. Deshalb ein paar Regeln:

  • Kurz: Je kürzer die URI je besser
  • Baumstruktur: Die URI sollte die Baumstruktur des Objekt-/Datengraphen repräsentieren
  • Lesbar: Klartext hilft
  • Voraussagbar: Die Reaktion des Servers entspricht der Inituition beim Lesen des URI
  • Substantive: URIs adressieren etwas, also ist das Wort eine Sache, keine Aktion. Wird eine Aktion gebraucht, hängt diese hinten an
  • QueryString I: Ja, darf man benutzen, aber nur für genau dies: query (Abfragen/Suchen), beispielsweise /books/search?filter=title&value=JADE
  • QueryString II: Nein, wenn Parameter benötigt werden, schreibt man /books/select/quarter=2;year=2016
  • Deterministisch: Gleiche URI ergibt immer dieselbe Ressource
  • Statuslos: Kein Zustand auf dem Server hat Einfluss
  • Kanonisch: Wenn zwei URIs zur selben Ressource führen, muss die Alternative in der Antwort benannt werden

Weniger wichtig, aber für guten Stil sinnvoll:

  • Nur Kleinschreibung benutzen — Camel-case und ähnliches ist hier eher störend
  • Bindestriche statt Unterstriche — book-review ist besser als book_review für Suchmaschinen
  • Plural nutzen, wenn es der Kontext erwartet (books, wenn es sich um mehrere handelt)
  • Wenn Abrufe aus Kollektionen erfolgen, sollte dies sichtbar sein: /books/book/3. Dann muss aber der Abruf /books technisch möglich sein und alle Bücher liefern. Wenn aber die Kollektion nicht geliefert werden kann, reicht /book/3.
  • Keine Leerzeichen — früher oder später sieht man nur noch %20-Fragmente

HTTP

In REST werden spezifische HTTP-Kommandos benutzt, um Aktionen auf dem Server auszulösen. Konkret eingesetzt werden:

  • GET: Abrufen einer Ressource
  • POST: Ändern oder Auslösen einer Aktion
  • PUT: Erzeugen einer Ressource
  • DELETE: Löschen einer Ressource
  • PATCH: Ändern eines Teils einer Ressource
  • HEAD: Metadaten anfordern
  • OPTIONS: Erlaubte Aktionen auf einer Ressource

Es ist nicht zwingend notwendig, dies mit SQL zu vergleichen, ein einfaches Mapping kann REST aber durchaus darstellen:

HTTP (REST) SQL
GET SELECT
POST UPDATE
PUT INSERT
DELETE DELETE

In HTTP sieht das beispielhaft folgendermaßen aus:

POST /book/2605

name=Neuer Artikelname

Hierbei ist die URI ein relativer Pfad zur Ressource. basket bezeichnet die Route zu einem Controller, der sich um den Warenkorb kümmert. Die Route erwartet eine ID, die hier 2605 enthält. Damit ist im Warenkorb ein Element mit dem Primärschlüssel 2605 gemeint. Dieses Element hat eine Eigenschaft name der der neue Text „Neuer Artikelname“ zugewiesen wird.

Mittels PUT wird eine Ressource wie folgt erzeugt:

PUT /book

<book>
  <title>JADE</title>
  <desc>
    Die Template-Engine JADE
  </desc>
  <price>2,99</price>
  <type>Paperback</type>
</book>

Da eines der Merkmale von REST die Selbstbeschreibung ist, gibt PUT einen Link zu neuen Ressource zurück:

HTTP/1.1 201 OK
Content-Type: text/xml;
Content-Length: 34

http://shop.texxtoor.de/book/2605

Das Löschen der Ressource erfolgt ähntlich:

DELETE /book/2605

MIME

MIME steht für Multipurpose Internet Mail Extensions und wurde ursprünglich dazu entwickelt, Dokumente in E-Mails einzubetten. Dabei wird eine beschreibende Kopfzeile (header) benutzt, um das ursprüngliche Format anzuzeigen. Der Client kann dies dann wieder herstellen. Typisch ist die Zweiteilung des Formats und die Benutzung der Kopfzeile Content-Type:

gruppe/detail

Für ein Bild sieht das nun folgendermaßen aus:

Content-Type: image/jpeg

Eine genaue Beschreibung, die über das hier für REST benötigte hinausgeht, finden Sie auf Wikipedia.

Für REST wird folgendes benutzt:

  • text/xml
  • application/json

JSON

Zur Kommunikation zwischen Client und Server wird JSON eingesetzt wird. JSON (JavaScript Object Notation), gesprochen wie der Name „Jes’n“, ist ein kompaktes Format in lesbarer Textform zum Zweck des Datenaustauschs zwischen Anwendungen. Obwohl der Name auf eine alleinige Verwendung in JavaScript hindeutet, ist JSON ein unabhängiges Format, das theoretisch in jeder Programmiersprache eingesetzt werden kann.

Der am meisten betonte Unterschied von JSON zu XML ist die etwas kompaktere Kodierung von Datenstrukturen, wodurch im Gegensatz zu XML weniger Verwaltungsdaten produziert werden. Außerdem kann JSON beispielsweise in JavaScript direkt in ein JavaScript-Objekt umgesetzt werden. XML ist hingegen vielseitiger als JSON einsetzbar, das keine Auszeichnungssprache, sondern nur ein Datenaustauschformat ist. XML genießt weiterhin eine weitere Verbreitung. Beide Formate sind nicht unbedingt zum repräsentieren von großen Binärdaten geeignet.

JSON kennt Objekte, Arrays, Zeichenketten, Zahlen, Boolesche Werte und null. Daten können beliebig verschachtelt werden, beispielsweise ist ein Array von Objek-ten möglich. Als Zeichenkodierung benutzt JSON UTF-8.

Die JSON-Formatdefinition

Ein Objekt wird mit geschweiften Klammern umschlossen { }. Es kann eine durch Kommata geteilte, ungeordnete Liste von Eigenschaften enthalten.

Eine Eigenschaft besteht aus einem Schlüssel und einem Wert, getrennt durch einen Doppelpunkt. Der Schlüssel ist eine Zeichenkette. Der Wert ist ein Objekt, ein Array, eine Zeichenkette, eine Zahl oder einer der Ausdrücke true, false oder null. Ein Array beginnt und endet mit eckigen Klammern [ ]. Es kann eine durch Kommata geteilte, geordnete Liste von Werten enthalten. Eine Zeichenkette beginnt und endet mit Anführungszeichen („). Sie kann Unicode-Zeichen und Escape-Sequenzen enthalten. Ein Boolescher Wert wird durch die Ausdrücke true bzw. false dargestellt –- ohne Anführungszeichen. Eine Zahl ist eine Folge der Ziffern 0−9. Diese Folge kann durch ein negatives Vorzeichen −- eingeleitet und einen Dezimalpunkt unterbrochen sein. Die Zahl kann durch die Angabe eines Exponenten e oder E ergänzt werden, dem ein Vorzeichen „+“ oder „-“ und eine Folge der Ziffern 0-9 folgt. Leerraumzeichen sind beliebig verwendbar.

{
  "CreditCard"    : "Visa",
  "Number"        : "1234-5678-9012-3456",
  "Owner"         :
  {
    "LastName"    : "Krause",
    "Firstname"   : "Jörg",
    "Gender"        : "\"male\"",
    "Preferences" : [
      "Golf",
      "Reading",
      "Badminton"
    ],
    "Age"         : null
  },
  "Deckung"       : 10000,
  "Währung"       : "EURO"
} 

Wenn Sie mehr über JSON lesen möchten, könnten folgende Quellen interessant sein:

  • json.org bietet eine deutsche Einführung auf der offiziellen JSON-Seite.
  • Die RFC 4627 definiert mit application/json einen weiteren MIME-Typ.

Das Format ATOM

ATOM steht für Atom Syndication Format, ein plattformunabhängiges Format zum Austausch von Feeds. Es hat damit denselben Zweck wie das bekanntere RSS, das in der neuesten Version 2.0 für Really Simple Syndication steht. ATOM gilt als designierter Nachfolger von RSS 2.0. ATOM selbst ist für verschiedene Zwecke definiert, wobei hier auf ASF (ATOM Syndication Format) Bezug genommen wird. Neben der reinen Feed-Verteilung kann ATOM für Newsletter und ähnliche Zwecke eingesetzt werden. ATOM wurde in der RFC 4278 veröffentlicht. Der MIME-Typ ist application/atom+xml.

<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <author>
    <name>Jörg Krause</name>
  </author>
  <id>urn:uuid:60a76c80-9926-9905-1964-0003939e0af6</id>

  <entry>
    <title>Neues aus der Web-Welt</title>
    <link href="http://hanser.de/2010/08/08/atom-wcf"/>
    <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-01723243189a</id>
    <updated>2016-12-08T12:50:07Z</updated>
    <summary>Alles über Web</summary>
    <content>Hier steht der gesamte Text</content>
  </entry>
</feed> 

In Node-Anwendungen wird man ATOM nur einsetzen, wenn Clients dies explizit fordern. Der Einsatz von JSON ist deutlich einfacher und schneller.

REST
Markiert in: