REST? Ganz einfach… oder doch nicht?

5 Okt

Heute will ich im Rahmen meiner MA „REST-API für ginkgo“ etwas zu REST schreiben. Wer generell die REST-Prinzipien kennt, kann direkt zum unteren Teil des zugegeben langen Posts gehen.

Representational State Transfer (REST) ist ein Architekturstil, den Roy Thomas Fielding, einer der Designer der HTTP-Spezifikation, im Rahmen seiner Doktorarbeit „Architectural Styles and the Design of Network-based Software Architectures“ entwickelte. Fielding zeigt, dass die bereits in den 90er Jahren definierten Webtechnologien den heutigen Anforderungen der Datenübertragung gerecht werden können ohne den Protokollstack komplexer zu machen.
Die durch den REST-Architekturstil festgelegten Restriktionen sollen Netzwerklatenz reduzieren und gleichzeitig Skalierbarkeit und lose Koppelung maximieren.

Die Charakteristika von REST:

  • Ressourcen & Adressierbarkeit

Ressourcen sind das zentrale Konzept in REST. Eine Ressource kann nahezu jede beliebige Information sein, die sich jedoch eindeutig identifizieren lassen muss. Einige Ressourcen sind elektronisch, wie z.B. ein Eintrag in einem Weblog, andere entstammen der realen Welt, beispielweise ein Auto.

3 Ressourcen:

http://www.example.org/haus
http://www.example.org/cuvif52dn
http://www.example.org/auto/64

  • Einheitliche Schnittstelle

Jede Ressource unterstützt den gleichen Satz an Operationen- dies sind die insgesamt acht Methoden des RFC 2616 (HTTP), von denen sechs praktische Relevanz haben:
GET, HEAD, PUT, POST, DELETE, OPTIONS

GET http://www.example.org/cuvif52dn

liefert eine Repräsentation der Ressource „http://www.example.org/cuvif52dn“

  • Repräsentationen & Hypermedia

Ressourcen an sich werden nie über ein Netzwerk übertragen. Jegliche Interaktionen mit Ressourcen erfolgen über deren Repräsentationen. Auf Basis von HTTP Content Negotiation können sich die Kommunikationspartner dynamisch auf eine Repräsentation eines bestimmten Formates einigen.

2 Repräsentationen der Ressource „http://www.example.org/auto/64“:
# Request
GET http://www.example.org/auto/64 Host: http://www.example.org
Accept: application/json

# Response
HTTP/1.1
200 OK
Content-Type: application/json;charset=UTF-8;

{
„name“: „Audi“,
„nummer“: „1234-5678-9012-3456“,
„waehrung“: „EURO“,
„farbe“: „blau“
}

# Request
GET http://www.example.org/auto/64 Host: http://www.example.org
Accept: application/x-www-form-urlencoded

# Response
HTTP/1.1
200 OK
Content-Type: application/x-www-form-urlencoded;charset=UTF-8;

name=Audi&nummer=1234-5678-9012-3456&waehrung=EURO&farbe=blau

Hypermedia spielt bei REST ebenfalls eine entscheidende Rolle. In den Repräsentationen von Ressourcen sind Links enthalten, die auf andere Ressourcen zeigen und mögliche Zustandsänderungen vorgeben. Die zugegeben unhandliche Abkürzung ist hier HATEOAS (Hypermedia as the Engine of Application State).

  • Zustandslosigkeit

Die Interaktion eines Klienten mit einem RESTful Web Service muss zustandslos sein. Dies wird erreicht, indem eine HTTP-Anfrage selbst alle zu ihrer Bearbeitung benötigten Informationen enthält. Eine jede Anfrage ist unabhängig von allen anderen (es gibt keine Sessions oder Cookies!). Deswegen auch der Name „State Transfer“: Eine Anwendung bewegt sich von einem Zustand zum nächsten Zustand.

———————————————————————————————————–

———————————————————————————————————–

Soweit also alles ganz verständlich. Es gibt ja auch schon genug REST-APIs, die diesen Stil umsetzen… Oder etwa nicht?

Wie ich schon erzählt hatte, habe ich mich in meiner BA bereits mit REST beschäftigt und habe tatsächlich keinen einzigen Service gefunden, der diesen Stil wirklich umsetzt! Roy Fielding macht hierauf auch in seinem schon legendären Blogbeitrag aufmerksam:

Was machen die meisten existierenden APIs also „falsch“?
Eine sehr schöne Präsentation hierzu:

Zusammengefasst:
Flickrs  „REST-API“ ist ein sehr gutes Beispiel dafür, wie man HTTP vergewaltigen kann:
Alle Anfragen gehen gegen die selbe Adresse, es werden Methoden im RPC-Stil aufgerufen, es gibt keine Ressourcen und die HTTP-Methoden werden nicht eingesetzt.

GET http://api.flickr.com/services/rest/?method=flickr.contacts.getList&page=3

POST http://api.flickr.com/services/rest/?method=flickr.blogs.postPhoto

Besser macht es schon die Twitter-API:
Hier sind Ressourcen identifizierbar und zumindest werden GET, POST und DELETE eingesetzt (keine Benutzung von PUT zum Updaten!)

GET http://api.twitter.com/1/friendships/incoming
POST https://api.twitter.com/1/lists/subscribers/create

(„create“ ist hier eine schlechte Namenswahl, weil dies an RPC erinnert)

Eine produktiv genutzte API, die dem REST-Stil sehr Nahe kommt, ist die Netflix-API:
Hier sind Ressourcen identifizierbar, alle HTTP-Verben werden korrekt eingesetzt und ganz wichtig: Die Antworten enthalten Links zu anderen Ressourcen inkl. ihrer semantischen Bedeutung.

Eine Repräsentation der User-Ressource sieht z.B. so aus:

GET http://api.netflix.com/users/T1PambOVJXcoWzNRQEyacp76BnRn0TIJdxKGyklbY0srg-

Repräsentation:
<user>
<user_id>T1PambOVJXcoWzNRQEyacp76BnRn0TIJdxKGyklbY0srg-</user_id>
<first_name>Jane</first_name>
<last_name>Smith</last_name>
<can_instant_watch>true</can_instant_watch>
<link href=“http://api.netflix.com/users/T1PambOVJXcoWzNRQEyacp76BnRn0TIJdxKGyklbY0srg-/rental_history&#8220; rel=“http://schemas.netflix.com/rental_history&#8220; title=“rental history““>
<link href=“http://api.netflix.com/users/T1PambOVJXcoWzNRQEyacp76BnRn0TIJdxKGyklbY0srg-/recommendations&#8220; rel=“http://schemas.netflix.com/recommendations&#8220; title=“recommendations“/>
<link href=“http://api.netflix.com/users/T1PambOVJXcoWzNRQEyacp76BnRn0TIJdxKGyklbY0srg-/ratings&#8220; rel=“http://schemas.netflix.com/ratings&#8220; title=“ratings“/>
</user>

Will man nun z.B. die Rental-Histoy eines Nutzers abrufen, wird clientseitig keine neue Adresse entlang vorgegebener Pfade zusammengebaut, sondern dem Link mit der semantischen Bedeutung (rel) „http://schemas.netflix.com/rental_history&#8220; gefolgt; hier: „http://api.netflix.com/users/T1PambOVJXcoWzNRQEyacp76BnRn0TIJdxKGyklbY0srg-/rental_history&#8220;.
Im besten Fall ist ein Client bis auf die Basisadresse „http://api.netflix.com&#8220; völlig unabhängig von der weiteren URL-Struktur- er folgt einfach nur den verfügbaren Links.

Das ist genauso, wie wir das vom herkömmlichen Surfen im Internet kennen: Wir geben nicht http://ddi.uni-paderborn.de/studium/ddifaq.html in die Adressleiste ein, sondern starten bei http://ddi.uni-paderborn.de.
Und genau DAS ist REST.

Und warum machen das viele APIs nicht? Dies werde ich als Nächstes erforschen und dann berichten. Ganz offensichtlich steigen die Anforderungen aber an die Verarbeitungslogik auf Clientseite bei Benutzung solch einer API.

P.S.: Ich habe mich nun dafür entschieden,  die URL und die API zu sagen. Laut Duden kann es auch der URL und das API heißen.

Schreibe einen Kommentar

Trage deine Daten unten ein oder klicke ein Icon um dich einzuloggen:

WordPress.com-Logo

Du kommentierst mit Deinem WordPress.com-Konto. Abmelden / Ändern )

Twitter-Bild

Du kommentierst mit Deinem Twitter-Konto. Abmelden / Ändern )

Facebook-Foto

Du kommentierst mit Deinem Facebook-Konto. Abmelden / Ändern )

Google+ Foto

Du kommentierst mit Deinem Google+-Konto. Abmelden / Ändern )

Verbinde mit %s

%d Bloggern gefällt das: