09.05.2014 Aufrufe

Die ressourcenorientierte Architektur - beim O'Reilly Verlag

Die ressourcenorientierte Architektur - beim O'Reilly Verlag

Die ressourcenorientierte Architektur - beim O'Reilly Verlag

MEHR ANZEIGEN
WENIGER ANZEIGEN

Sie wollen auch ein ePaper? Erhöhen Sie die Reichweite Ihrer Titel.

YUMPU macht aus Druck-PDFs automatisch weboptimierte ePaper, die Google liebt.

Frischer Wind für<br />

Web Services durch REST<br />

Deutsche<br />

Ausgabe<br />

Web Services<br />

mit<br />

REST<br />

O’Reilly<br />

Leonard Richardson & Sam Ruby<br />

Deutsche Übersetzung von<br />

Thomas Demmig & Sebastian Tussing


Web Services mit REST<br />

Leonard Richardson und Sam Ruby<br />

Deutsche Übersetzung von<br />

Thomas Demmig und Sebastian Tussing<br />

Beijing · Cambridge · Farnham · Köln · Paris · Sebastopol · Taipei · Tokyo


<strong>Die</strong> Informationen in diesem Buch wurden mit größter Sorgfalt erarbeitet. Dennoch können<br />

Fehler nicht vollständig ausgeschlossen werden. <strong>Verlag</strong>, Autoren und Übersetzer übernehmen<br />

keine juristische Verantwortung oder irgendeine Haftung für eventuell verbliebene Fehler und<br />

deren Folgen.<br />

Alle Warennamen werden ohne Gewährleistung der freien Verwendbarkeit benutzt und sind<br />

möglicherweise eingetragene Warenzeichen. Der <strong>Verlag</strong> richtet sich im Wesentlichen nach den<br />

Schreibweisen der Hersteller. Das Werk einschließlich aller seiner Teile ist urheberrechtlich<br />

geschützt. Alle Rechte vorbehalten einschließlich der Vervielfältigung, Übersetzung,<br />

Mikroverfilmung sowie Einspeicherung und Verarbeitung in elektronischen Systemen.<br />

Kommentare und Fragen können Sie gerne an uns richten:<br />

O’Reilly <strong>Verlag</strong><br />

Balthasarstr. 81<br />

50670 Köln<br />

Tel.: 0221/9731600<br />

Fax: 0221/9731608<br />

E-Mail: kommentar@oreilly.de<br />

Copyright der deutschen Ausgabe:<br />

© 2007 by O’Reilly <strong>Verlag</strong> GmbH & Co. KG<br />

1. Auflage 2007<br />

<strong>Die</strong> Originalausgabe erschien 2007 unter dem Titel<br />

RESTful Web Services bei O’Reilly Media, Inc.<br />

<strong>Die</strong> Darstellung eines Fuchskusu im Zusammenhang<br />

mit dem Thema Web Services mit REST ist ein<br />

Warenzeichen von O’Reilly Media, Inc.<br />

Bibliografische Information Der Deutschen Bibliothek<br />

<strong>Die</strong> Deutsche Bibliothek verzeichnet diese Publikation in der<br />

Deutschen Nationalbibliografie; detaillierte bibliografische Daten<br />

sind im Internet über http://dnb.ddb.de abrufbar.<br />

Übersetzung und deutsche Bearbeitung: Thomas Demmig, Sebastian Tussing, Mannheim<br />

Lektorat: Volker Bombien, Köln<br />

Fachliche Begutachtung: Dr. Claudia Nölker, Bielefeld<br />

Korrektorat: Eike Nitz, Köln<br />

Satz: DREI-SATZ, Husby<br />

Umschlaggestaltung: Michael Oreal, Köln<br />

Produktion: Andrea Miß, Karin Driesen, Köln<br />

Belichtung, Druck und buchbinderische Verarbeitung:<br />

Druckerei Kösel, Krugzell; www.koeselbuch.de<br />

ISBN 978-3-89721-727-0<br />

<strong>Die</strong>ses Buch ist auf 100% chlorfrei gebleichtem Papier gedruckt.


First<br />

Inhalt<br />

Vorwort . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .<br />

Einführung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .<br />

IX<br />

XI<br />

Max.<br />

Linie<br />

1 Das programmierbare Web und seine Bewohner . . . . . . . . . . . . . . . . . . . . . . . 1<br />

Lebewesen im programmierbaren Web . . . . . . . . . . . . . . . . . . . . . . . . . . . 5<br />

HTTP: Dokumente in Umschlägen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6<br />

Methodeninformation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8<br />

Fokusinformation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12<br />

<strong>Die</strong> konkurrierenden <strong>Architektur</strong>en . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14<br />

Technologien im programmierbaren Web . . . . . . . . . . . . . . . . . . . . . . . . . 20<br />

Weitere Terminologie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22<br />

2 Clients für Web Services schreiben . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25<br />

Web Services sind Web-Sites . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25<br />

del.icio.us: <strong>Die</strong> Beispielanwendung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28<br />

Einen Request stellen: HTTP-Bibliotheken . . . . . . . . . . . . . . . . . . . . . . . . 31<br />

Verarbeiten der Response: XML-Parser . . . . . . . . . . . . . . . . . . . . . . . . . . . 42<br />

JSON-Parser: Umgang mit serialisierten Daten . . . . . . . . . . . . . . . . . . . . . 48<br />

Clients ganz einfach – mit WADL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52<br />

3 Was macht REST-konforme Services anders? . . . . . . . . . . . . . . . . . . . . . . . . . . 55<br />

Einführung in den Simple Storage Service . . . . . . . . . . . . . . . . . . . . . . . . . 55<br />

Objektorientiertes Design von S3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57<br />

Ressourcen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58<br />

HTTP-Responsecodes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60<br />

Ein S3-Client . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62<br />

Signierte Requests und Zugriffskontrolle . . . . . . . . . . . . . . . . . . . . . . . . . . 72<br />

Verwenden der S3-Client-Bibliothek . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79<br />

Max.<br />

Linie<br />

This is the Title of the Book, eMatter Edition<br />

Copyright © 2007 O’Reilly & Associates, Inc. All rights reserved.<br />

| V


Transparente Clients durch ActiveResource . . . . . . . . . . . . . . . . . . . . . . . 80<br />

Abschlusswort . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86<br />

Links<br />

Max.<br />

Linie<br />

4 <strong>Die</strong> <strong>ressourcenorientierte</strong> <strong>Architektur</strong> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89<br />

Ressourcenorientiert: Warum? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90<br />

Was ist eine Ressource? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91<br />

URIs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92<br />

Adressierbarkeit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95<br />

Zustandslosigkeit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 98<br />

Repräsentationen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103<br />

Verweise und Verbindungshaftigkeit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 106<br />

<strong>Die</strong> einheitliche Schnittstelle . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 110<br />

Das war’s! . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 119<br />

5 Entwurf von nur lesbaren <strong>ressourcenorientierte</strong>n Services . . . . . . . . . . . . . . . . 121<br />

Ressourcendesign . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 123<br />

Anforderungen in nur lesbare Ressourcen umwandeln . . . . . . . . . . . . . . . 124<br />

Welche Daten sind notwendig? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 125<br />

Unterteilen der Daten in Ressourcen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 128<br />

Benennen der Ressourcen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 133<br />

Entwerfen Sie Ihre Repräsentationen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 140<br />

Verbinden der Ressourcen miteinander . . . . . . . . . . . . . . . . . . . . . . . . . . . 154<br />

<strong>Die</strong> HTTP-Response . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 156<br />

Zusammenfassung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 160<br />

6 Entwurf von les- und schreibbaren <strong>ressourcenorientierte</strong>n Services . . . . . . . . . 161<br />

Benutzerkonten als Ressourcen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 162<br />

Eigene Orte . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 177<br />

Ein Blick zurück auf den Kartenservice . . . . . . . . . . . . . . . . . . . . . . . . . . . 187<br />

7 Eine Service-Implementierung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 189<br />

Ein Social Bookmarking-Web Service . . . . . . . . . . . . . . . . . . . . . . . . . . . . 189<br />

Welche Daten werden benötigt? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 191<br />

Ressourcendesign . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 193<br />

Vom Client kommende Repräsentation(en) entwerfen . . . . . . . . . . . . . . . 207<br />

Repräsentation(en) zum Senden an den Client entwerfen . . . . . . . . . . . . . 210<br />

Ressourcen miteinander verbinden . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 211<br />

Was soll passieren? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 212<br />

Was kann schiefgehen? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 213<br />

Controller-Code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 214<br />

Model-Code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 233<br />

Was muss der Client wissen? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 237<br />

Max.<br />

Linie<br />

VI | Inhalt<br />

This is the Title of the Book, eMatter Edition<br />

Copyright © 2007 O’Reilly & Associates, Inc. All rights reserved.


Rechts<br />

8 Best Practices: REST und ROA . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 243<br />

Ressourcenorientierte Grundlagen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 243<br />

Der allgemeine ROA-Ablauf . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 244<br />

Addressierbarkeit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 245<br />

Zustand und Zustandslosigkeit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 246<br />

Connectedness . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 247<br />

<strong>Die</strong> einheitliche Schnittstelle . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 247<br />

Das ist wirklich wichtig . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 250<br />

Ressourcendesign . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 258<br />

URI-Design . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 264<br />

Ausgehende Repräsentationen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 265<br />

Eingehende Repräsentationen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 266<br />

Versionierung des Service . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 267<br />

Permanente URIs vs. lesbare URIs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 268<br />

Standardeigenschaften von HTTP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 270<br />

PUT und DELETE vortäuschen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 286<br />

Ärger mit Cookies . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 286<br />

Warum einem HTTP-Client trauen? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 288<br />

Max.<br />

Linie<br />

9 <strong>Die</strong> Bausteine eines Service . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 295<br />

Repräsentationsformate . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 295<br />

Zusammengestellte Kontrollflüsse . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 312<br />

Hypermedia-Technologien . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 325<br />

10 <strong>Die</strong> <strong>ressourcenorientierte</strong> <strong>Architektur</strong> vs. dicke Web Services . . . . . . . . . . . . . . 343<br />

Welche Probleme versuchen dicke Web Services zu lösen? . . . . . . . . . . . . 344<br />

SOAP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 345<br />

WSDL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 349<br />

UDDI . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 355<br />

Sicherheit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 356<br />

Reliable Messaging . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 358<br />

Transaktionen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 359<br />

BPEL, ESB und SOA . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 360<br />

Zusammenfassung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 362<br />

11 Ajax-Anwendungen als REST-Clients . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 363<br />

Von AJAX zu Ajax . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 364<br />

<strong>Die</strong> Ajax-<strong>Architektur</strong> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 364<br />

Ein del.icio.us-Beispiel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 366<br />

<strong>Die</strong> Vorteile von Ajax . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 369<br />

<strong>Die</strong> Nachteile von Ajax . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 370<br />

REST geht besser . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 371<br />

Max.<br />

Linie<br />

This is the Title of the Book, eMatter Edition<br />

Copyright © 2007 O’Reilly & Associates, Inc. All rights reserved.<br />

Inhalt | VII


Durchführung des Requests . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 372<br />

Verarbeitung der Response . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 374<br />

JSON . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 375<br />

Behalten Sie nicht die Vorteile von REST für sich . . . . . . . . . . . . . . . . . . . 376<br />

Cross-Browser-Probleme und Ajax- Bibliotheken . . . . . . . . . . . . . . . . . . . 378<br />

Das Sicherheitsmodell des Browsers untergraben . . . . . . . . . . . . . . . . . . . 382<br />

Links<br />

12 Frameworks für REST-konforme Services . . . . . . . . . . . . . . . . . . . . . . . . . . . . 391<br />

Ruby on Rails . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 391<br />

Restlet . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 396<br />

Django . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 409<br />

A Einige Ressourcen für REST und einige REST-konforme Ressourcen . . . . . . . . . 421<br />

Standards und Leitfäden . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 421<br />

Services, die Sie verwenden können . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 423<br />

B <strong>Die</strong> wichtigsten 42 HTTP-Responsecodes . . . . . . . . . . . . . . . . . . . . . . . . . . . . 429<br />

Drei bis sieben Statuscodes: Das Minimum . . . . . . . . . . . . . . . . . . . . . . . . 430<br />

1xx: Meta . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 431<br />

2xx: Erfolgreich . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 433<br />

3xx: Weiterleitung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 436<br />

4xx: Fehler auf Clientseite . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 440<br />

5xx: Fehler auf Serverseite . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 447<br />

C <strong>Die</strong> HTTP-Header-Hitliste . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 451<br />

Standard-Header . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 452<br />

Header außerhalb des Standards . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 468<br />

Index . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 471<br />

Max.<br />

Linie<br />

Max.<br />

Linie<br />

VIII | Inhalt<br />

This is the Title of the Book, eMatter Edition<br />

Copyright © 2007 O’Reilly & Associates, Inc. All rights reserved.


First<br />

Kapitel 4<br />

KAPITEL 4<br />

Hier Mini IVZ eingeben!<br />

<strong>Die</strong> <strong>ressourcenorientierte</strong> <strong>Architektur</strong><br />

Erstellen auf den<br />

Arbeitsseiten<br />

(siehe Muster)<br />

Max.<br />

Linie<br />

Abstand untere Tabellenlinie zu Textanfang 1,8 cm<br />

-> also: manuell auf den Arbeitsseiten ziehen!!!<br />

Ich habe Ihnen zwar die Möglichkeiten von REST gezeigt, habe dabei aber nicht systematisch<br />

erklärt, wie sie strukturiert sind oder wie man sie auch verfügbar macht. In<br />

diesem Kapitel beschreibe ich eine konkrete REST-konforme <strong>Architektur</strong>: die <strong>ressourcenorientierte</strong><br />

<strong>Architektur</strong> (ROA). ROA ist ein Weg, um ein Problem in einen<br />

REST-konformen Web Service umzuwandeln: eine Kombination aus URIs, HTTP<br />

und XML, die so wie der Rest des Webs funktioniert und die Programmierer gerne<br />

nutzen werden.<br />

In Kapitel 1 habe ich REST-konforme Web Services anhand der Beantwortung von<br />

zwei Fragen klassifiziert. <strong>Die</strong>se Antworten entsprechen zwei der vier definierenden<br />

Features von REST:<br />

• <strong>Die</strong> Fokusinformation (»Warum sollte der Server diese Daten senden und nicht<br />

jene?«) befindet sich in dem URI. Das ist das Prinzip der Adressierbarkeit.<br />

• <strong>Die</strong> Methoden-Information (»Warum sollte der Server die Daten schicken und<br />

nicht löschen?«) befindet sich in der HTTP-Methode. Es gibt nur ein paar<br />

HTTP-Methoden und man weiß schon vorher, was sie tun. Das ist das Prinzip<br />

der einheitlichen Schnittstelle.<br />

In diesem Kapitel stelle ich die Kernbestandteile der <strong>ressourcenorientierte</strong>n<br />

<strong>Architektur</strong> vor: Ressourcen (natürlich), ihre Namen, ihre Repräsentationen und die<br />

Verweise zwischen ihnen. Ich erläutere die Eigenschaften der ROA: Adressierbarkeit,<br />

Zustandslosigkeit, Verbindungshaftigkeit und die einheitliche Schnittstelle.<br />

Ich zeige, wie die Web-Technologien (HTTP, URIs und XML) diese Bestandteile<br />

implementieren, um die Eigenschaften möglich zu machen.<br />

In den vorigen Kapiteln habe ich Konzepte präsentiert, indem ich bestehende Web<br />

Services vorgestellt habe, wie zum Beispiel S3. Ich will das in diesem Kapitel fortführen,<br />

möchte aber Konzepte zusätzlich deutlich machen, indem ich auf bestehende<br />

Web-Sites verweise. Ich habe Sie hoffentlich schon davon überzeugt, dass<br />

Web-Sites auch Web Services sind und dass viele Web-Anwendungen (wie zum<br />

Beispiel Suchmaschinen) REST-konforme Web Services darstellen. Wenn ich über<br />

Max.<br />

Linie<br />

<strong>Die</strong>s ist ein Auszug aus dem Buch „Web Services mit REST“, ISBN 978-3-89721-727-0<br />

This is http://www.oreilly.de/catalog/restfulwsger/<br />

the Title of the Book, eMatter Edition<br />

<strong>Die</strong>ser Auszug unterliegt dem Urheberrecht. © <strong>O'Reilly</strong> <strong>Verlag</strong> 2008<br />

Copyright © 2007 O’Reilly & Associates, Inc. All rights reserved.<br />

| 89


Max.<br />

Linie<br />

abstrakte Konzepte wie Adressierbarkeit spreche, ist es hilfreich, Ihnen reale URIs zu<br />

zeigen, die Sie in Ihren Web-Browser eintippen können, um die Konzepte auch im<br />

wahren Leben zu sehen.<br />

Ressourcenorientiert: Warum?<br />

Warum komme ich hier mit einem neuen Begriff an, <strong>ressourcenorientierte</strong> <strong>Architektur</strong>?<br />

Warum schreibe ich nicht einfach REST? Nun, auf dem Buch steht vorne REST<br />

drauf und ich sage auch, dass alles in der <strong>ressourcenorientierte</strong>n <strong>Architektur</strong> RESTkonform<br />

ist. Aber REST ist keine <strong>Architektur</strong>, sondern eine Zusammenstellung von<br />

Designkriterien. Sie können sagen, dass eine <strong>Architektur</strong> diese Kriterien besser<br />

erfüllt als eine andere, aber es gibt nicht die eine »REST-<strong>Architektur</strong>«.<br />

Bisher neigten die Leute eher dazu, jedes Mal <strong>beim</strong> Entwerfen ihrer Services eine<br />

neue <strong>Architektur</strong> nur für diesen einen Fall zu entwerfen – und zwar entsprechend<br />

ihrem eigenen Verständnis von REST. Das offensichtlichste Ergebnis davon ist die<br />

große Anzahl von REST-RPC-Hybrid-Web Services, von denen ihre Erbauer<br />

behaupten, sie seien REST-konform. Ich versuche, das zu beenden, indem ich eine<br />

Reihe konkreter Regeln für das Erstellen von Web Services vorstelle, die wirklich<br />

REST-konform sind. In den nächsten beiden Kapiteln werde ich sogar einfache<br />

Vorgehensweisen zeigen, denen Sie folgen können, um Anforderungen in Ressourcen<br />

umzuwandeln. Wenn Sie meine Regeln nicht mögen, bekommen Sie zumindest<br />

eine Idee davon, was Sie ändern können, ohne dabei weniger REST-konform zu werden.<br />

Als Sammlung von Designkriterien ist REST sehr allgemein. Insbesondere ist es nicht<br />

an das Web gebunden. Nichts in REST hängt von den Mechanismen von HTTP oder<br />

der Struktur von URIs ab. Aber ich spreche hier über Web Services, daher verbinde<br />

ich die <strong>ressourcenorientierte</strong> <strong>Architektur</strong> explizit mit den Web-Technologien. Ich<br />

möchte darüber reden, wie man REST mit HTTP und URIs umsetzen kann – in spezifischen<br />

Programmiersprachen. Wenn die Zukuft REST-konforme <strong>Architektur</strong>en<br />

schafft, die nicht auf dem Web aufsetzen, werden deren Best Practices wohl ähnlich<br />

wie ROA aussehen, die Details sich aber unterscheiden. Wir werden das noch näher<br />

betrachten, wenn wir dorthin gelangen.<br />

<strong>Die</strong> klassische Definition von REST enthält eine Menge Freiräume, die von den<br />

Anwendern mit Eigenkreationen gefüllt wurden. Ich gehe mit Absicht weiter als Roy<br />

Fielding in seiner Dissertation oder das W3C in seinen Standards: Ich möchte einige<br />

der »offenen« Bereiche klarer gestalten, so dass die Eigenentwürfe sich zu wohldefinierten<br />

Best Practices entwickeln. Selbst wenn REST eine <strong>Architektur</strong> wäre,<br />

fände ich es nicht fair, meine <strong>Architektur</strong> genauso zu benennen. Ich würde meine<br />

empirischen Beobachtungen und Vorschläge mit den allgemeiner gehaltenen Gedanken<br />

derer verbinden, die das Web aufgebaut haben.<br />

Links<br />

Max.<br />

Linie<br />

90 | Kapitel 4: <strong>Die</strong> <strong>ressourcenorientierte</strong> <strong>Architektur</strong><br />

This is the Title of the Book, eMatter Edition<br />

Copyright © 2007 O’Reilly & Associates, Inc. All rights reserved.<br />

<strong>Die</strong>s ist ein Auszug aus dem Buch „Web Services mit REST“, ISBN 978-3-89721-727-0<br />

http://www.oreilly.de/catalog/restfulwsger/<br />

<strong>Die</strong>ser Auszug unterliegt dem Urheberrecht. © <strong>O'Reilly</strong> <strong>Verlag</strong> 2008


Rechts<br />

Mein letzter Grund für einen neuen Begriff ist, dass »REST« in Glaubenskriegen von<br />

Nerds verwendet wird. Seine Nutzung geschieht häufig im Zusammenhang mit der<br />

Meinung, dass es nur eine wirklich REST-konforme <strong>Architektur</strong> gibt – die, die der<br />

Sprecher bevorzugt. Leute, die andere REST-konforme <strong>Architektur</strong>en eher mögen,<br />

widersprechen. <strong>Die</strong> REST-Gemeinschaft ist zersplittert, obwohl es eine gemeinsame<br />

Basis in Bezug auf Dinge wie den Wert von URIs und HTTP gibt.<br />

Idealerweise sollte es keine Glaubenskriege geben, aber ich habe genug gesehen, um<br />

zu wissen, dass dieser Wunsch nicht für ihr Ende sorgen wird. Daher gebe ich meiner<br />

Philosophie, wie REST-konforme Anwendungen entworfen werden sollten, einen<br />

anderen Namen. Wenn diese Ideen – was zwangsläufig geschehen wird – als Munition<br />

in solchen Kriegen genutzt werden, können Leute, die mit mir nicht übereinstimmen,<br />

Elemente der <strong>ressourcenorientierte</strong>n <strong>Architektur</strong> von anderen RESTkonformen<br />

<strong>Architektur</strong>en und von REST im Allgemeinen trennen. Klarheit ist der<br />

erste Schritt zum Verständnis.<br />

<strong>Die</strong> Begriffe »ressourcenorientiert« und »<strong>ressourcenorientierte</strong> <strong>Architektur</strong>« wurden<br />

genutzt, um REST-konforme <strong>Architektur</strong>en im Allgemeinen zu beschreiben. 1 Ich<br />

denke nicht, dass »<strong>ressourcenorientierte</strong> <strong>Architektur</strong>« ein komplett neuer Begriff ist,<br />

aber ich glaube, dass meine Verwendung gut zu früheren Nutzungen passt und es<br />

besser ist, diesen Begriff zu nutzen, als für REST als Ganzes zu sprechen.<br />

Was ist eine Ressource?<br />

Eine Ressource ist alles, was wichtig genug ist, um als eigenständiges Etwas referenziert<br />

zu werden. Wenn Ihre Benutzer »einen Hypertext-Verweis dafür erstellen,<br />

Annahmen darüber erstellen oder widerrufen, eine Darstellung davon holen oder<br />

speichern, alles oder Teile davon per Referenz in andere Darstellungen übernehmen,<br />

es kommentieren oder andere Operationen darauf ausführen wollen«, sollten Sie es<br />

zu einer Ressource machen. 2<br />

Normalerweise ist eine Ressource etwas, das auf einem Computer gespeichert und<br />

als Bit-Stream dargestellt werden kann: ein Dokument, eine Zeile in einer Datenbank<br />

oder das Ergebnis eines Algorithmus. Eine Ressource kann ein physikalisches Objekt<br />

Max.<br />

Linie<br />

1 <strong>Die</strong> älteste Erwähnung von »ressourcenorientiert«, die ich gefunden habe, ist in einem Artikel aus der<br />

IBM developerWorks von 2004 von James Snell: »Resource-oriented vs. activity-oriented Web services«<br />

(http://www-128.ibm.com/developerworks/xml/library/ws-restvsoap/). Alex Bunardzic hat »<strong>ressourcenorientierte</strong><br />

<strong>Architektur</strong>« im August 2006 genutzt, bevor dieses Buch angekündigt worden war: http://<br />

jooto.com/blog/index.php/2006/08/08/replacing-service-oriented-architecture-with-resource-orientedarchitecture/.<br />

Ich stimme nicht mit allem in diesen Artikeln überein, aber ich gebe zu, dass sie die Terminologie<br />

schon zuvor genutzt haben.<br />

2 »The Architecture of the World Wide Web« (http://www.w3.org/TR/2004/REC-webarch-20041215/<br />

#p39), worin viel Zitierwürdiges zu finden ist, so zum Beispiel: »Softwareentwickler sollten davon ausgehen,<br />

dass eine Nutzung der gleichen URIs in mehreren Anwendungen nützlich sein wird, auch wenn<br />

das nicht gleich offensichtlich ist.« Das könnte der Schlachtruf für die ROA sein.<br />

Max.<br />

Linie<br />

Was ist eine Ressource?<br />

This is the Title of the Book, eMatter Edition<br />

| 91<br />

Copyright © 2007 O’Reilly & Associates, Inc. All rights reserved.<br />

<strong>Die</strong>s ist ein Auszug aus dem Buch „Web Services mit REST“, ISBN 978-3-89721-727-0<br />

http://www.oreilly.de/catalog/restfulwsger/<br />

<strong>Die</strong>ser Auszug unterliegt dem Urheberrecht. © <strong>O'Reilly</strong> <strong>Verlag</strong> 2008


sein wie ein Apfel oder ein abstraktes Konzept wie Mut, allerdings ist (wie wir später<br />

sehen werden) die Darstellung solcher Ressourcen meist eher enttäuschend.<br />

Hier ein paar mögliche Ressourcen:<br />

• Version 1.0.3 des Software-Release<br />

• die letzte Version des Software-Release<br />

• der erste Weblog-Eintrag am 24. Oktober 2006<br />

• eine Straßenkarte für Little Rock, Arkansas<br />

• Informationen über Quallen<br />

• ein Verzeichnis mit Ressourcen über Quallen<br />

• die nächstgrößere Primzahl nach 1024<br />

• die nächsten fünf Primzahlen nach 1024<br />

• die Verkaufszahlen für das 4. Quartal 2004<br />

• die Beziehung zwischen Alice und Bob<br />

• eine Liste der offenen Fehler in der Fehlerdatenbank<br />

Links<br />

URIs<br />

Was macht aus einer Ressource eine Ressource? Sie muss mindestens einen URI<br />

haben. Der URI ist der Name und die Adresse einer Ressource. Wenn eine Information<br />

keinen URI hat, ist sie keine Ressource und befindet sich auch nicht wirklich im<br />

Web, höchstens als Datenhäppchen, das andere Ressourcen beschreibt.<br />

Erinnern Sie sich an die Beispielsession in der Einführung, bei der ich ein wenig Spaß<br />

mit HTTP 0.9 hatte? Lassen Sie uns annehmen, das dies ein HTTP-0.9-Request für<br />

http://www.example.com/hello.txt wäre:<br />

Client-Request<br />

GET /hello.txt<br />

Server-Response<br />

Hello, world!<br />

Ein HTTP-Client arbeitet mit einer Ressource, indem er sich mit dem Server verbindet,<br />

der sie hostet (in diesem Fall www.example.com) und dem Server eine Methode<br />

(»GET«) sowie einen Pfad zur Ressource (»/hello.txt«) schickt. Das heutige HTTP 1.<br />

1 ist etwas komplexer als 0.9, funktioniert aber im Prinzip noch genauso. Sowohl der<br />

Server als auch der Pfad kommen aus dem URI der Ressource.<br />

Client-Request<br />

Server-Response<br />

Max.<br />

Linie<br />

GET /hello.txt HTTP/1.1<br />

Host: www.example.com<br />

200 OK<br />

Content-Type: text/plain<br />

Hello, world!<br />

Max.<br />

Linie<br />

92 | Kapitel 4: <strong>Die</strong> <strong>ressourcenorientierte</strong> <strong>Architektur</strong><br />

This is the Title of the Book, eMatter Edition<br />

Copyright © 2007 O’Reilly & Associates, Inc. All rights reserved.<br />

<strong>Die</strong>s ist ein Auszug aus dem Buch „Web Services mit REST“, ISBN 978-3-89721-727-0<br />

http://www.oreilly.de/catalog/restfulwsger/<br />

<strong>Die</strong>ser Auszug unterliegt dem Urheberrecht. © <strong>O'Reilly</strong> <strong>Verlag</strong> 2008


Rechts<br />

<strong>Die</strong> Prinzipien hinter den URIs sind von Tim Berners-Lee sehr gut in »Universal<br />

Resource Identifiers – Axioms of Web Architecture« beschrieben (http://www.w3.<br />

org/DesignIssues/Axioms). In diesem Abschnitt möchte ich die Prinzipien vorstellen,<br />

die hinter dem Zusammenstellen von URIs und ihrer Zuweisung an Ressourcen stehen.<br />

Max.<br />

Linie<br />

Der URI ist die grundlegende Technologie des Web. Es gab schon<br />

vor HTML Hypertext-Systeme, und Internetprotokolle vor HTTP,<br />

aber sie konnten nicht miteinander sprechen. Der URI verband all<br />

diese Internetprotokolle zu einem Web, so wie TCP/IP die Netzwerke<br />

wie Usenet, Bitnet und CompuServe zu einem Internet vereint<br />

hat. Dann schluckte das Web diese anderen Protokolle und merzte<br />

sie aus, so wie es das Internet mit privaten Netzwerken tat.<br />

Heute surfen wir im Web (und nicht in Gopher), laden Dateien aus<br />

dem Web (und nicht von FTP-Sites), suchen Veröffentlichungen im<br />

Web (und nicht in WAIS) und reden miteinander im Web (und<br />

nicht in Usenet-Newsgroups). Versionsverwaltungssysteme wie Subversion<br />

und arch arbeiten über das Web – im Gegensatz zum CVS-<br />

Protokoll. Selbst E-Mails wandern langsam ins Web.<br />

Das Web merzt alle anderen Protokolle aus, weil es etwas hat, was<br />

den meisten Protokollen fehlt: eine einfache Möglichkeit, jedes verfügbare<br />

Element zu beschriften. Jede Ressource im Web hat mindestens<br />

einen URI. Sie können einen URI auf eine Reklametafel<br />

schreiben. <strong>Die</strong> Leute sehen diese Tafel, geben den URI in ihren Web-<br />

Browser ein und kommen direkt zu der Ressource, die Sie ihnen zeigen<br />

wollten. Es mag seltsam erscheinen, aber diese tagtägliche Interaktion<br />

war nicht möglich, bevor die URIs erfunden wurden.<br />

URIs sollten beschreibend sein<br />

Hier kommt der erste Punkt, bei dem die ROA auf den zurückhaltenden Empfehlungen<br />

des REST-Dokuments und der W3C-Empfehlungen aufbaut. Ich schlage vor,<br />

dass eine Ressource und ihr URI intuitiv zusammenpassen sollten. Hier sind ein paar<br />

gute URIs für die Ressourcen, die ich weiter oben aufgeführt habe:<br />

• http://www.example.com/software/releases/1.0.3.tar.gz<br />

• http://www.example.com/software/releases/latest.tar.gz<br />

• http://www.example.com/weblog/2006/10/24/0<br />

• http://www.example.com/landkarte/strassen/USA/AR/Little_Rock<br />

• http://www.example.com/wiki/Quallen<br />

• http://www.example.com/suche/Quallen<br />

• http://www.example.com/nextprime/1024<br />

• http://www.example.com/next-5-primes/1024<br />

• http://www.example.com/verkaeufe/2004/Q4<br />

Max.<br />

Linie<br />

This is the Title of the Book, eMatter Edition<br />

Copyright © 2007 O’Reilly & Associates, Inc. All rights reserved.<br />

<strong>Die</strong>s ist ein Auszug aus dem Buch „Web Services mit REST“, ISBN 978-3-89721-727-0<br />

http://www.oreilly.de/catalog/restfulwsger/<br />

<strong>Die</strong>ser Auszug unterliegt dem Urheberrecht. © <strong>O'Reilly</strong> <strong>Verlag</strong> 2008<br />

URIs | 93


• http://www.example.com/beziehungen/Alice;Bob<br />

• http://www.example.com/bugs/nach-zustand/open<br />

URIs sollten eine Struktur haben. Sie sollten vorhersehbar sein. Sie sollten nicht<br />

/suche/Quallen für Quallen und /i-want-to-know-about/Mäuse für Mäuse aufrufen<br />

müssen. Wenn ein Client die Struktur der URIs für die Services kennt, kann er seine<br />

eigenen Einstiegspunkte in den Service aufbauen. Das erleichtert es den Clients,<br />

Ihren Service auf Arten zu nutzen, die Sie gar nicht berücksichtigt haben.<br />

Das ist keine uneingeschränkt gültige Regel, wie wir im Abschnitt »Benennen der<br />

Ressourcen« auf Seite 133 sehen werden. URIs müssen technisch gesehen überhaupt<br />

keine Struktur haben oder vorhersehbar sein, aber ich denke, sie sollten es. <strong>Die</strong>s ist<br />

eine der Regeln guten Web-Designs, und sie zeigt sich sowohl bei REST-konformen<br />

als auch bei REST-RPC-Hybrid-Web Services.<br />

Links<br />

Max.<br />

Linie<br />

<strong>Die</strong> Beziehung zwischen URIs und Ressourcen<br />

Lassen Sie uns ein paar Grenzfälle betrachten. Können zwei Ressourcen gleich sein?<br />

Können zwei URIs die gleiche Ressource ansprechen? Kann ein einzelner URI zwei<br />

Ressourcen ansprechen?<br />

Per Definition können keine zwei Ressourcen gleich sein. Wenn sie es wären, wären<br />

Sie nur eine Ressource. Allerdings kann es Zeitenabschnitte geben, in denen zwei<br />

verschiedene Ressourcen auf die gleichen Daten verweisen. Wenn das aktuelle<br />

Software-Release die Version 1.0.3 ist, werden http://www.example.com/software/releases/1.0.3.tar.gz<br />

und http://www.example.com/software/releases/latest.tar.gz eine<br />

Zeit lang auf dieselbe Datei verweisen. Aber die Ideen hinter diesen beiden URIs sind<br />

verschieden: Eine wird immer auf eine bestimmte Version zeigen, während die<br />

andere auf das zeigt, was zum Zeitpunkt des Zugriffs die neueste Version ist. Das<br />

sind zwei Konzepte und zwei Ressourcen. Sie werden nicht auf latest verweisen,<br />

wenn Sie einen Fehler in Version 1.0.3 melden.<br />

Eine Ressource kann einen oder mehrere URIs haben. <strong>Die</strong> Verkaufszahlen, die unter<br />

http://www.example.com/sales/2004/Q4 verfügbar sind, lassen sich vielleicht auch<br />

über http://www.example.com/sales/Q42004 abrufen. Wenn eine Ressource mehrere<br />

URIs hat, ist es einfacher für die Clients, darauf zu verweisen. Als Nachteil mindert<br />

jeder weitere URI den Wert aller anderen. Manche Clients verwenden einen URI,<br />

manche einen anderen, und es gibt keine automatische Möglichkeit, zu überprüfen,<br />

ob all diese URIs auf die gleiche Ressource verweisen.<br />

Eine Möglichkeit, dies zu umgehen, ist es, mehrere URIs für die gleiche<br />

Ressource bereitzustellen, aber nur einen von ihnen als »kanonischen«<br />

URI für diese Ressource festzulegen. Wenn ein Client den<br />

kanonischen URI anfordert, schickt der Server die entsprechenden<br />

Daten zusammen mit dem Responsecode 200 (»OK«) zurück. For-<br />

Max.<br />

Linie<br />

94 | Kapitel 4: <strong>Die</strong> <strong>ressourcenorientierte</strong> <strong>Architektur</strong><br />

This is the Title of the Book, eMatter Edition<br />

Copyright © 2007 O’Reilly & Associates, Inc. All rights reserved.<br />

<strong>Die</strong>s ist ein Auszug aus dem Buch „Web Services mit REST“, ISBN 978-3-89721-727-0<br />

http://www.oreilly.de/catalog/restfulwsger/<br />

<strong>Die</strong>ser Auszug unterliegt dem Urheberrecht. © <strong>O'Reilly</strong> <strong>Verlag</strong> 2008


Rechts<br />

dert ein Client einen der anderen URIs an, sendet der Server den<br />

Responsecode 303 (»See also«) zusammen mit dem kanonischen<br />

URI. Der Client kann nicht feststellen, ob zwei URIs auf die gleiche<br />

Ressource zeigen, aber er kann zwei HEAD-Requests abschicken und<br />

kontrollieren, ob ein URI zum anderen weiterleitet oder ob beide zu<br />

einem dritten URI verweisen.<br />

Man kann auch alle URIs gleich behandeln, aber der »kanonische«<br />

URI im Response-Header Content-Location immer dann angeben,<br />

wenn ein Request einen nicht kanonische URI anfordert.<br />

Max.<br />

Linie<br />

Der Aufruf von sales/2004/Q4 bringt Ihnen vielleicht den gleichen Bytestream wie<br />

sales/Q42004, da es sich um verschiedene URIs für dieselbe Ressource handelt:<br />

»Verkäufe im letzten Quartal 2004«. Der Aufruf von releases/1.0.3.tar.gz führt<br />

vielleicht zum selben Bytestream wie releases/latest.tar.gz, aber es handelt sich<br />

um unterschiedliche Ressourcen, die verschiedene Dinge repräsentieren: »Version<br />

1.0.3« und »die letzte Version«.<br />

Jeder URI bezeichnet exakt eine Ressource. Wenn er für mehr als eine Ressource<br />

stünde, wäre er kein Universal Resource Identifier. Aber wenn Sie einen URI<br />

abfragen, wird Ihnen der Server vielleicht Informationen über mehrere Ressourcen<br />

liefern: die eine, die Sie angefordert haben, und andere, die dazu in Beziehung stehen.<br />

Wenn Sie eine Web-Seite holen wollen, enthält diese normalerweise Informationen<br />

über sich selbst, aber auch Verweise auf andere Web-Seiten. Wenn Sie ein S3-<br />

Bucket mit einem Client für Amazons S3 laden, erhalten Sie ein Dokument, das<br />

Informationen über das Bucket, aber auch über dazu in Beziehung stehende<br />

Ressourcen enthält: die Objekte im Bucket.<br />

Adressierbarkeit<br />

Nachdem ich nun Ressourcen und ihre URIs eingeführt habe, kann ich zwei Features<br />

der ROA detaillierter behandeln: Adressierbarkeit und Zustandslosigkeit.<br />

Eine Anwendung ist dann adressierbar, wenn sie die interessanten Aspekte ihrer<br />

Daten als Ressourcen bereitstellt. Da Ressourcen durch URIs zur Verfügung gestellt<br />

werden, bietet eine adressierbare Anwendung eines URI für jedes Informationselement<br />

an, das sie eventuell herausgeben könnte. Das ist normalerweise eine<br />

unendlich große Zahl von URIs.<br />

Aus Sicht des Endanwenders ist die Adressierbarkeit der wichtigste Aspekt jeder<br />

Web-Site und Web-Anwendung. Benutzer sind schlau und ignorieren oder umgehen<br />

so gut wie jede Einschränkung, wenn die Daten nur interessant genug sind – aber es<br />

ist sehr schwer, fehlende Adressierbarkeit zu umgehen.<br />

Stellen Sie sich einen realen URI für eine Ressource »Verzeichnis der Ressourcen zu<br />

Quallen« http://www.google.com/search?q=Qualle vor. <strong>Die</strong>se Suche nach Quallen ist<br />

Max.<br />

Linie<br />

Adressierbarkeit | 95<br />

This is the Title of the Book, eMatter Edition<br />

Copyright © 2007 O’Reilly & Associates, Inc. All rights reserved.<br />

<strong>Die</strong>s ist ein Auszug aus dem Buch „Web Services mit REST“, ISBN 978-3-89721-727-0<br />

http://www.oreilly.de/catalog/restfulwsger/<br />

<strong>Die</strong>ser Auszug unterliegt dem Urheberrecht. © <strong>O'Reilly</strong> <strong>Verlag</strong> 2008


genauso real wie der URI http://www.google.com. Wenn HTTP nicht adressierbar<br />

oder die Such-Engine von Google keine adressierbare Web-Anwendung wäre,<br />

könnte ich diesen URI nicht in einem Buch veröffentlichen. Ich müsste Ihnen Folgendes<br />

erzählen: »Öffnen Sie eine Web-Verbindung zu google.com, geben Sie im<br />

Suchfeld ›Qualle‹ ein und klicken Sie dann auf den Button ›Google Search‹.«<br />

Links<br />

Das ist keine rein akademische Sorge. Bis Mitte der 90er Jahre, als<br />

URIs mit ftp:// beliebt wurden, um Dateien auf FTP-Sites zu<br />

beschreiben, mussten die Leute so ähnlich vorgehen: »Öffne eine<br />

anonyme FTP-Session auf ftp.example.com. Dann wechsle in das<br />

Verzeichnis pub/files/ und lade die Datei file.txt herunter.« URIs<br />

ermöglichten es, FTP genauso adressierbar zu machen wie HTTP.<br />

Jetzt schreiben die Leute einfach: »Lade die Datei ftp://ftp.example.<br />

com/pub/files/file.txt herunter.« <strong>Die</strong> Schritte sind die gleichen, sie<br />

können jetzt aber von einem Rechner durchgeführt werden.<br />

Max.<br />

Linie<br />

Aber HTTP und Google sind beide adressierbar, daher kann ich diesen URI in einem<br />

Buch angeben. Sie können sie lesen und eintippen. Wenn Sie das tun, landen Sie<br />

dort, wo ich auch war, als ich mit der Web-Anwendung von Google gearbeitet habe.<br />

Sie können dann diese Seite als Lesezeichen ablegen und sie später wieder besuchen.<br />

Sie können auf einer eigenen Web-Seite darauf verweisen. Sie können den URI an<br />

jemand anderen mailen. Wenn HTTP nicht adressierbar wäre, müssten Sie die ganze<br />

Seite herunterladen und die HTML-Datei als Anhang mitschicken.<br />

Um Bandbreite zu sparen, können Sie einen HTTP-Proxy-Cache in Ihrem lokalen<br />

Netzwerk einrichten. Wenn jemand das erste Mal http://www.google.com/<br />

search?q=Qualle anfordert, speichert der Cache eine lokale Kopie des Dokuments.<br />

Wenn das nächste Mal jemand diesen URI eingibt, kann der Cache seine gespeicherte<br />

Kopie übermitteln, anstatt sie erneut herunterzuladen. All das ist nur möglich,<br />

wenn jede Seite einen eindeutigen String als Kennzeichen hat: eine Adresse.<br />

Es ist sogar möglich, URIs zu verketten, also einen URI als Eingabe für einen anderen<br />

zu verwenden. Sie können einen externen Web Service nutzen, um den HTML-Code<br />

einer Seite zu validieren, oder um den auf der Seite enthaltenen Text in eine andere<br />

Sprache zu übersetzen. <strong>Die</strong>se Web Services erwarten einen URI als Eingabe. Wenn<br />

HTTP nicht adressierbar wäre, hätten Sie keine Möglichkeit, ihnen mitzuteilen, mit<br />

welcher Ressource sie arbeiten sollen.<br />

Der S3-Service von Amazon ist adressierbar, weil jedes Bucket und jedes Objekt<br />

seinen eigenen URI besitzt, so wie auch die Bucket-Liste. Buckets und Objekte, die<br />

noch nicht existieren, sind noch keine Ressourcen, aber auch sie haben ihre eigenen<br />

URIs: Sie können eine Ressource erzeugen, indem Sie einen PUT-Request an ihren<br />

URI schicken.<br />

Das Dateisystem auf Ihrem eigenen Computer ist ein weiteres adressierbares System.<br />

Anwendungen an der Befehlszeile können einen Pfad zu einer Datei übernehmen<br />

Max.<br />

Linie<br />

96 | Kapitel 4: <strong>Die</strong> <strong>ressourcenorientierte</strong> <strong>Architektur</strong><br />

This is the Title of the Book, eMatter Edition<br />

Copyright © 2007 O’Reilly & Associates, Inc. All rights reserved.<br />

<strong>Die</strong>s ist ein Auszug aus dem Buch „Web Services mit REST“, ISBN 978-3-89721-727-0<br />

http://www.oreilly.de/catalog/restfulwsger/<br />

<strong>Die</strong>ser Auszug unterliegt dem Urheberrecht. © <strong>O'Reilly</strong> <strong>Verlag</strong> 2008


Rechts<br />

und dann lustige Dinge damit anstellen. <strong>Die</strong> Felder in einer Tabellenkalkulation sind<br />

ebenfalls adressierbar – sie können den Namen eines Felds in eine Formel stecken,<br />

die dann den aktuellen Wert dieses Felds nutzen wird. URIs sind die Dateipfade und<br />

Feldadressen des Web.<br />

Adressierbarkeit ist eine der besten Eigenschaften von Web-Anwendungen. Sie erleichtert<br />

es Clients, Web-Sites anders zu nutzen, als sich das die ursprünglichen<br />

Designer überlegt hatten. Folgen Sie dieser einen Regel, bringt REST Ihnen und<br />

Ihren Anwendern viele Vorteile. Das ist der Grund, warum REST-RPC-Services so<br />

verbreitet sind: Sie kombinieren Adressierbarkeit mit dem Programmiermodell, in<br />

dem Prozeduren aufgerufen werden. Das ist der Grund, warum ich die Ressourcen<br />

so prominent in »<strong>ressourcenorientierte</strong>r <strong>Architektur</strong>« stehen habe: weil sie die<br />

Dinger sind, die sich adressieren lassen.<br />

Das scheint ganz natürlich zu sein – die Art und Weise, wie das Web funktionieren<br />

sollte. Leider arbeiten viele Web-Anwendungen aber nicht so. Das gilt insbesondere<br />

für Ajax-Anwendungen. Wie ich in Kapitel 11 zeigen werden, sind die meisten Ajax-<br />

Anwendungen nur Clients für REST-konforme oder hybride Web Services. Aber<br />

wenn Sie diese Clients so nutzen, als ob es Web-Sites wären, werden Sie feststellen,<br />

dass sie sich nicht wie Web-Sites anfühlen.<br />

Lassen Sie uns nicht weiter darauf herumhacken, sondern unsere Reise zu den Google-Anwendungen<br />

fortführen, indem wir uns den Online-E-Mail-Service Google Mail<br />

anschauen. Aus Sicht des Endandwenders gibt es nur einen URI für Google Mail:<br />

https://mail.google.com/. Was auch immer Sie tun, welche Daten Sie auch von Google<br />

Mail laden oder dort ablegen – Sie werden niemals einen anderen URI zu Gesicht<br />

bekommen. <strong>Die</strong> Ressource »E-Mails zu Quallen« ist nicht adressierbar, wogegen es<br />

die »Web-Seiten über Quallen« von Google sind. 3 Aber wie ich in Kapitel 11 zeige,<br />

gibt es eine Web-Site, die adressierbar ist. <strong>Die</strong> Liste der E-Mails zum Thema Quallen<br />

hat einen URI: https://mail.google.com/mail/?q=Quallen&search=query&view=tl. Das<br />

Problem ist, dass Sie kein Benutzer dieser Web-Site sind. <strong>Die</strong> Site ist in Wirklichkeit<br />

ein Web Service, und der eigentliche Empfänger ist ein JavaScript-Programm, das<br />

innerhalb Ihres Web-Browsers läuft. 4 Der Web Service von Google Mail ist adressierbar,<br />

aber die Web-Anwendung von Google, die ihn nutzt, ist es nicht.<br />

Max.<br />

Linie<br />

3 Vergleichen Sie die Ajax-Schnittstelle mit der besser adressierbaren Version von Google Mail, die Sie<br />

erhalten, wenn Sie die Anwendung mit dem URI https://mail.google.com/mail/?ui=html aufrufen. Bei<br />

dieser Schnittstelle in klassischem HTML ist die Ressource »E-Mails zum Thema Quallen« adressierbar.<br />

4 Andere Konsumenten dieses Web Services nutzen die Bibliothek libgmail für Python (http://libgmail.<br />

sourceforge.net/).<br />

Max.<br />

Linie<br />

Adressierbarkeit | 97<br />

This is the Title of the Book, eMatter Edition<br />

Copyright © 2007 O’Reilly & Associates, Inc. All rights reserved.<br />

<strong>Die</strong>s ist ein Auszug aus dem Buch „Web Services mit REST“, ISBN 978-3-89721-727-0<br />

http://www.oreilly.de/catalog/restfulwsger/<br />

<strong>Die</strong>ser Auszug unterliegt dem Urheberrecht. © <strong>O'Reilly</strong> <strong>Verlag</strong> 2008


Max.<br />

Linie<br />

Zustandslosigkeit<br />

Adressierbarkeit ist eines der vier Hauptfeatures der ROA. Das zweite ist die<br />

Zustandslosigkeit. Ich werde Ihnen zwei Definitionen von Zustandslosigkeit geben:<br />

eine allgemeinere und eine praktischere, die zur ROA passt.<br />

Zustandslosigkeit bedeutet, dass jeder HTTP-Request in vollständiger Isolation<br />

geschieht. Wenn der Client einen HTTP-Request abschickt, enthält dieser alle Informationen,<br />

die für den Server notwendig sind, um die Anfrage zu erfüllen. Der Server<br />

verlässt sich niemals auf Informationen aus früheren Requests. Wenn solche Informationen<br />

wichtig gewesen wären, hätte der Client sie mit dem aktuellen Request<br />

erneut mitgeschickt.<br />

Wenn Sie das Ganze praktischer betrachten, stellen Sie sich die Zustandslosigkeit in<br />

Begriffen der Adressierbarkeit vor. Adressierbarkeit besagt, dass jede interessante<br />

Information, die der Server zur Verfügung stellen kann, auch als Ressource bereitstehen<br />

sollte und ihren eigenen URI bekommt. Zustandslosigkeit besagt, dass die<br />

möglichen Zustände des Servers ebenfalls Ressourcen sind und ebenso ihre eigenen<br />

URIs bekommen sollten. Der Client sollte den Server nicht in einen bestimmten<br />

Zustand zwingen müssen, damit er für eine bestimmte Anfrage empfänglich ist.<br />

Im menschlichen Web sehen Sie sich häufig Situationen gegenüber, in denen der<br />

»Zurück«-Button Ihres Browsers nicht richtig funktioniert und Sie in Ihrem Browser-<br />

Verlauf nicht vor- und zurückgehen können. Manchmal liegt das daran, dass Sie eine<br />

unwiderrufliche Aktion ausgelöst haben, wie zum Beispiel einen Weblog-Eintrag zu<br />

veröffentlichen oder ein Buch zu kaufen, aber häufig ist der Grund schlicht, dass eine<br />

Web-Site die Prinzipien der Zustandslosigkeit verletzt. Solch eine Site erwartet, dass<br />

Sie Anfragen in einer bestimmten Reihenfolge abschicken: A, B und dann C. Sie gerät<br />

durcheinander, wenn Sie Anfrage B ein zweites Mal abschicken, anstatt mit Anfrage<br />

C fortzufahren.<br />

Lassen Sie uns nochmals das Suchbeispiel nehmen. Eine Such-Engine ist ein Web<br />

Service mit einer unendlichen Zahl möglicher Zustände: Es gibt mindestens einen für<br />

jeden String, nach dem Sie suchen. Jeder Zustand hat seinen eigenen URI. Sie können<br />

den Service nach einem Verzeichnis mit Ressourcen über Mäuse fragen: http://<br />

www.google.com/search?q=M%E4use. Sie können nach einem Verzeichnis mit<br />

Ressourcen über Quallen fragen: http://www.google.com/search?q=Quallen. Wenn<br />

Sie sich nicht sicher sind, wie man einen URI vollständig selber erstellt, können Sie<br />

den Service nach einem Formular dafür fragen: http://www.google.com/.<br />

Wenn Sie nach einem Verzeichnis der Ressourcen zu Mäusen oder Quallen fragen,<br />

erhalten Sie nicht das gesamte Verzeichnis. Sie bekommen eine einzelne Seite des<br />

Verzeichnisses: eine Liste mit (zum Beispiel) zehn Ressourcen, die nach Ansicht der<br />

Such-Engine Ihre Anfrage am Besten beantworten. Um mehr zu bekommen, müssen<br />

Sie zusätzliche HTTP-Requests absetzen. <strong>Die</strong> zweite und die folgenden Seiten sind<br />

Links<br />

Max.<br />

Linie<br />

98 | Kapitel 4: <strong>Die</strong> <strong>ressourcenorientierte</strong> <strong>Architektur</strong><br />

This is the Title of the Book, eMatter Edition<br />

Copyright © 2007 O’Reilly & Associates, Inc. All rights reserved.<br />

<strong>Die</strong>s ist ein Auszug aus dem Buch „Web Services mit REST“, ISBN 978-3-89721-727-0<br />

http://www.oreilly.de/catalog/restfulwsger/<br />

<strong>Die</strong>ser Auszug unterliegt dem Urheberrecht. © <strong>O'Reilly</strong> <strong>Verlag</strong> 2008


Rechts<br />

eigene Zustände der Anwendung und müssen ihre eigenen URIs haben, zum Beispiel<br />

http://www.google.com/search?q=Quallen&start=10. Wie bei jeder adressierbaren<br />

Ressource können Sie diesen Zustand der Anwendung an jemand anderen übermitteln,<br />

ihn zwischenspeichern oder zu Ihren Lesezeichen stecken und später dorthin<br />

zurückkehren.<br />

Abbildung 4-1 ist ein einfaches Zustandsdiagramm, das zeigt, wie ein HTTP-Client<br />

mit vier Zuständen einer Such-Engine interagieren könnte.<br />

Such-Formular<br />

“Quallen”<br />

Request<br />

Request<br />

Response<br />

Response<br />

Response<br />

Initialer Zustand<br />

“Mäuse”,<br />

Seite 2<br />

Request<br />

Response<br />

“Mäuse”<br />

Request<br />

Abbildung 4-1: Eine zustandslose Such-Engine<br />

<strong>Die</strong>s ist eine zustandslose Anwendung, weil bei jedem Zugriff, den ein Client tätigt,<br />

wieder von vorn angefangen wird. Jeder Request ist völlig unabhängig von den<br />

anderen. Der Client kann Anfragen an diese Ressourcen beliebig häufig vornehmen<br />

und in beliebiger Reihenfolge. Er kann Seite 2 über »Mäuse« aufrufen, bevor er Seite<br />

1 anfordert (oder Seite 1 völlig ignorieren) – den Server wird es nicht kümmern.<br />

Im totalen Gegensatz dazu zeigt Abbildung 4-2 die gleichen Zustände, nun zustandsbehaftet<br />

angeordnet, wobei die Zustände sinnvoll ineinander übergehen können.<br />

<strong>Die</strong> meisten Desktop-Anwendungen sind so entworfen.<br />

Initialer Zustand<br />

Such-Formular<br />

“Mäuse”<br />

“Quallen”<br />

Max.<br />

Linie<br />

Abbildung 4-2: Eine zustandsbehaftete Such-Engine<br />

“Mäuse”,<br />

Seite 2<br />

Max.<br />

Linie<br />

Zustandslosigkeit | 99<br />

This is the Title of the Book, eMatter Edition<br />

Copyright © 2007 O’Reilly & Associates, Inc. All rights reserved.<br />

<strong>Die</strong>s ist ein Auszug aus dem Buch „Web Services mit REST“, ISBN 978-3-89721-727-0<br />

http://www.oreilly.de/catalog/restfulwsger/<br />

<strong>Die</strong>ser Auszug unterliegt dem Urheberrecht. © <strong>O'Reilly</strong> <strong>Verlag</strong> 2008


Max.<br />

Linie<br />

Das ist deutlich besser organisiert, und wenn HTTP so entworfen wäre, dass es<br />

zustandsbehaftete Interaktionen zulassen würde, könnten HTTP-Requests deutlich<br />

einfacher sein. Wenn der Client eine Session mit der Such-Engine starten würde,<br />

könnte er automatisch das Suchformular ausfüllen. Er müsste keinerlei Request-<br />

Daten schicken, da die erste Response vorherbestimmt wäre. Wenn der Client sich<br />

die ersten zehn Einträge im Mäuse-Verzeichnis angeschaut hätte und nun die Einträge<br />

11–20 sehen wollte, müsste er nur einen Request mit dem Inhalt »start=10«<br />

schicken. Er müsste nicht nach /search?q=mice&start=10 fragen und damit die initialen<br />

Vorgaben wiederholen: »Ich suche, und zwar speziell nach Mäusen.«<br />

Genau so funktioniert FTP: Es kennt ein »Arbeitsverzeichnis«, das während der gesamten<br />

Sitzung konstant bleibt, sofern Sie es nicht ändern. Sie können sich an einem<br />

FTP-Server anmelden, per cd zu einem bestimmten Verzeichnis wechseln und per<br />

get eine Datei aus diesem Verzeichnis holen. Dann nutzen Sie get erneut für eine<br />

andere Datei aus demselben Verzeichnis, ohne einen zweiten cd-Befehl ausführen zu<br />

müssen. Warum unterstützt HTTP das nicht?<br />

Zustände würden einzelne HTTP-Anfragen vereinfachen, aber das HTTP-Protokoll<br />

deutlich verkomplizieren. Ein FTP-Client ist weitaus komplizierter als ein HTTP-<br />

Client, und zwar genau aus dem Grund, dass der Session-Zustand zwischen Client<br />

und Server synchron gehalten werden muss. Das ist eine komplexe Aufgabe selbst in<br />

einem stabilen Netzwerk, was das Internet definitiv nicht ist.<br />

Eliminiert man den Zustand aus einem Protokoll, eliminiert man auch eine Reihe<br />

von Fehlerquellen. Der Server muss sich keine Sorgen um das Timeout eines Clients<br />

machen, da keine Interaktion länger als ein einzelner Request dauert. Der Server verliert<br />

nie die Übersicht darüber, »wo« sich jeder Client in der Anwendung befindet, da<br />

der Client alle notwendigen Informationen mit jeder Anfrage mitschickt. Der Client<br />

führt nie eine Aktion im falschen »Arbeitsverzeichnis« aus, nur weil der Server einen<br />

Zustand geändert hat, ohne es dem Client zu erzählen.<br />

Zustandslosigkeit bringt auch neue Features mit. Es ist einfacher, eine zustandslose<br />

Anwendung zum Lastausgleich auf mehrere Server zu verteilen. Da keine zwei<br />

Requests voneinander abhängig sind, können sie von zwei verschiedenen Servern<br />

verarbeitet werden, die sich nicht gegenseitig koordinieren müssen. Skalieren ist einfach:<br />

Man muss dem Load Balancer nur weitere Server hinzufügen. Eine zustandslose<br />

Anwendung lässt sich auch einfach cachen: Eine Software kann entscheiden, ob<br />

die Ergebnisse eines HTTP-Request gecachet werden können, indem nur der<br />

entsprechende Request angeschaut wird. Es gibt keine quälende Unsicherheit, ob<br />

der Zustand aus einer vorigen Anfrage die Cachebarkeit der aktuellen Anfrage beeinflusst.<br />

Der Client zieht aus der Zustandslosigkeit ebenfalls Vorteile. Ein Client kann das<br />

Mäuse-Verzeichnis ab Seite 50 verarbeiten, ein Lesezeichen für /search?q=<br />

Mäuse&start=500 speichern und eine Woche später wiederkommen, ohne sich durch<br />

Dutzende von vorigen Zuständen durcharbeiten zu müssen. Ein URI, der mitten<br />

Links<br />

Max.<br />

Linie<br />

100 | Kapitel 4: <strong>Die</strong> <strong>ressourcenorientierte</strong> <strong>Architektur</strong><br />

This is the Title of the Book, eMatter Edition<br />

Copyright © 2007 O’Reilly & Associates, Inc. All rights reserved.<br />

<strong>Die</strong>s ist ein Auszug aus dem Buch „Web Services mit REST“, ISBN 978-3-89721-727-0<br />

http://www.oreilly.de/catalog/restfulwsger/<br />

<strong>Die</strong>ser Auszug unterliegt dem Urheberrecht. © <strong>O'Reilly</strong> <strong>Verlag</strong> 2008


Rechts<br />

Max.<br />

Linie<br />

während einer langen HTTP-Sitzung abgesetzt wird, funktioniert genauso, als ob er als<br />

erster URI in einer neuen Session angefragt wird.<br />

Um Ihren Service adressierbar zu machen, müssen Sie ein wenig Aufwand treiben<br />

und die Daten Ihrer Anwendung in Ressourcen aufteilen. HTTP ist schon an sich ein<br />

zustandsloses Protokoll, daher erhalten Sie die Zustandslosigkeit automatisch, wenn<br />

Sie Web Services schreiben. Um das zu ändern, müssen Sie etwas tun.<br />

Um die Zustandslosigkeit aufzuheben, nutzen Sie am besten HTTP-Sessions, die von<br />

Ihrem Framework unterstützt werden. Sobald sich ein Benutzer auf Ihre Seiten begibt,<br />

erhält er einen eindeutigen String, der seine Session auf der Site identifiziert.<br />

Der String kann sich in einem Cookie befinden, oder die Site reicht den String in<br />

allen URIs weiter, die sie einem bestimmten Client zur Verfügung stellt. So sieht ein<br />

Session-Cookie aus, das von einer Rails-Anwendung gesetzt wurde:<br />

Set-Cookie: _session_id=c1c934bbe6168dcb904d21a7f5644a2d; path=/<br />

<strong>Die</strong>ser URI gibt die Session-ID in einer PHP-Anwendung weiter: http://www.example.com/forums?PHPSESSID=27314962133.<br />

Wichtig zu beachten ist dabei, das unsinnige hexadezimale oder dezimale Zahlen<br />

kein Zustand sind. Es handelt sich um einen Schlüssel zu einer Datenstruktur auf<br />

dem Server, und diese Datenstruktur enthält den Zustand. An zustandsbehafteten<br />

URIs gibt es nichts, was REST widerspricht: So kommuniziert der Server mögliche<br />

nächste Zustände an den Client weiter. (Aber Cookies sind nicht REST-konform,<br />

wie ich in Abschnitt »Ärger mit Cookies« auf Seite 286 besprechen werde. Um eine<br />

Web-Browser-Analogie zu verwenden: Cookies machen den »Zurück«-Button in<br />

einem Client für einen Web Service kaputt.)<br />

Betrachten Sie einmal die Query-Variable start=10 in einem URI, der in einer<br />

HTML-Seite eingebettet ist, die durch die Such-Engine von Google ausgeliefert<br />

wurde. Damit schickt der Server einen möglichen nächsten Zustand an den Client.<br />

Aber solche URIs müssen den Zustand enthalten und nicht nur einen Schlüssel zu<br />

einem Zustand liefern, der auf dem Server abgelegt ist. start=10 hat von sich aus<br />

Bedeutung, was bei PHPSESSID=27314962133 nicht der Fall ist. REST-konform zu sein<br />

erfordert, dass der Zustand auf Client-Seite vorhanden bleibt und an den Server bei<br />

jedem Request geschickt wird, der dies erfordert. Der Server kann den Client zu<br />

neuen Zuständen drängen, indem er zustandsbehaftete Verweise schickt, denen der<br />

Client folgen kann, aber er kann den Status nicht selber verwalten.<br />

Anwendungszustand vs. Ressourcen-Zustand<br />

Wenn wir uns über »Zustandslosigkeit« unterhalten, müssen wir uns fragen, was ein<br />

»Zustand« ist. Was ist der Unterschied zwischen persistenten Daten, also den nützlichen<br />

Daten auf Serverseite, wegen derer wir den Web Service vor allem nutzen, und<br />

diesem Zustand, den wir vom Server fern halten wollen? Der Flickr-Web Service lässt<br />

Max.<br />

Linie<br />

Zustandslosigkeit | 101<br />

This is the Title of the Book, eMatter Edition<br />

Copyright © 2007 O’Reilly & Associates, Inc. All rights reserved.<br />

<strong>Die</strong>s ist ein Auszug aus dem Buch „Web Services mit REST“, ISBN 978-3-89721-727-0<br />

http://www.oreilly.de/catalog/restfulwsger/<br />

<strong>Die</strong>ser Auszug unterliegt dem Urheberrecht. © <strong>O'Reilly</strong> <strong>Verlag</strong> 2008


Max.<br />

Linie<br />

Sie Bilder auf Ihr Konto hochladen, die dann auf dem Server gespeichert werden. Es<br />

wäre verrückt, den Client jedes seiner Bilder zusammen mit jedem Request an<br />

flickr.com schicken zu lassen, nur um den Server davon abzuhalten, irgendeinen<br />

Zustand speichern zu müssen. Das würde den ganzen Service ad absurdum führen.<br />

Aber was ist dann der Unterschied zwischen diesem Szenario und dem Zustand der<br />

Client-Session, von dem ich fordere, dass er vom Server fernbleibt?<br />

Das Problem liegt in der Terminologie. Zustandslosigkeit impliziert, dass es nur eine<br />

Art von Zustand gibt und dass der Server sich davon fernhalten sollte. Tatsächlich<br />

gibt es zwei Zustandsarten. Ich werde in diesem Buch von nun an zwischen dem<br />

Anwendungszustand, der auf dem Client, und dem Ressourcen-Zustand, der auf dem<br />

Server verwaltet werden sollte, unterscheiden.<br />

Wenn Sie eine Such-Engine verwenden, sind Ihre aktuelle Abfrage und die aktuelle<br />

Seite Teile des Anwendungszustands. <strong>Die</strong>ser Zustand unterscheidet sich für jeden<br />

Client. Sie können sich auf Seite 3 der Suchergebnisse für »Quallen« befinden,<br />

während ich mich auf Seite 1 der Suchergebnisse für »Mäuse« tummle. <strong>Die</strong> Seitennummer<br />

und die Abfrage sind verschieden, da wir unterschiedliche Pfade in der<br />

Anwendung eingeschlagen haben. Unsere jeweiligen Clients verwalten unterschiedliche<br />

Anwendungszustände.<br />

Ein Web Service muss sich nur dann um Ihren Anwendungszustand kümmern,<br />

wenn Sie tatsächlich einen Request stellen. Den Rest der Zeit weiß er nicht einmal,<br />

dass Sie existieren. Das bedeutet, dass immer dann, wenn ein Client einen Request<br />

absetzt, dieser alle Anwendungszustände enthält, die der Server benötigt, um die<br />

Anfrage zu verarbeiten. Es kann sein, dass der Server eine Seite mit Verweisen<br />

zurückschickt, die den Client über andere Requests informieren, die er in Zukunft<br />

stellen könnte. Aber danach kann er wieder alles vergessen, was er über den Client<br />

weiß, bis dieser die nächste Anfrage stellt. Das meine ich, wenn ich sage, dass ein<br />

Web Service »zustandslos« sein sollte. Der Client sollte dafür verantwortlich sein,<br />

seinen eigenen Weg durch die Anwendung selbst zu verwalten.<br />

Der Ressourcen-Zustand ist für jeden Client gleich, und sein Platz ist auf dem Server.<br />

Wenn Sie ein Bild in Flickr hochladen, erzeugen Sie eine neue Ressource: Das neue<br />

Bild hat seinen eigenen URI und kann das Ziel zukünftiger Requests sein. Sie können<br />

die Ressource »Bild« per HTTP laden, verändern und löschen. Jeder kann das tun.<br />

Das Bild ist ein Teil des Ressourcen-Zustands und bleibt auf dem Server, bis ein<br />

Client es löscht.<br />

Der Client-Zustand kann an Stellen auftauchen, an denen Sie ihn nicht erwarten<br />

würden. Viele Web Services wollen eine Registrierung, nach der Sie einen eindeutigen<br />

String erhalten (meist als API-Key oder Application Key bezeichnet). Sie<br />

schicken diesen Schlüssel bei jedem Request mit, und der Server verwendet ihn, um<br />

Ihre Anfragen auf eine bestimmte Obergrenze pro Tag einzuschränken. So ist zum<br />

Beispiel ein API Key für Googles auslaufende SOAP-Such-API für 1000 Requests pro<br />

Links<br />

Max.<br />

Linie<br />

102 | Kapitel 4: <strong>Die</strong> <strong>ressourcenorientierte</strong> <strong>Architektur</strong><br />

This is the Title of the Book, eMatter Edition<br />

Copyright © 2007 O’Reilly & Associates, Inc. All rights reserved.<br />

<strong>Die</strong>s ist ein Auszug aus dem Buch „Web Services mit REST“, ISBN 978-3-89721-727-0<br />

http://www.oreilly.de/catalog/restfulwsger/<br />

<strong>Die</strong>ser Auszug unterliegt dem Urheberrecht. © <strong>O'Reilly</strong> <strong>Verlag</strong> 2008


Rechts<br />

Max.<br />

Linie<br />

Tag gut. Das ist ein Anwendungszustand: Er unterscheidet sich für jeden Client.<br />

Nachdem Sie das Limit überschritten haben, ändert sich das Verhalten des Service<br />

drastisch: Bei Anfrage 1000 erhalten Sie Ihre Daten, bei Anfrage 1001 nur eine<br />

Fehlermeldung. Im Moment bin ich bei Anfrage 402, und der Service funktioniert für<br />

mich klasse.<br />

Natürlich kann man Clients nicht vertrauen, dieses Element des Anwendungszustands<br />

selbst zu verwalten: <strong>Die</strong> Versuchung zu schummeln, ist zu groß. Daher<br />

behalten Server diese Art von Anwendungszustand bei sich und verletzen damit das<br />

Prinzip der Zustandslosigkeit. Der API Key ist wie das Rails-Cookie _session_id ein<br />

Schlüssel für eine Client-Session auf Server-Seite, die einen Tag anhält. Das ist soweit<br />

vertretbar, man muss aber bei der Skalierbarkeit einen Preis dafür zahlen. Wenn der<br />

Service über mehrere Maschinen verteilt wird, muss jeder Rechner im Cluster wissen,<br />

dass Sie schon Request 1001 geschickt haben, während ich noch bei Nummer<br />

402 bin (der technische Begriff dafür ist die Session Replication), so dass jede<br />

Maschine weiß, dass sie Ihren Zugriff abblocken und meinen bearbeiten soll. Alternativ<br />

dazu muss der Load Balancer sicherstellen, dass jeder Ihrer Requests auf der<br />

gleichen Maschine im Cluster verarbeitet wird (Session Affinity). Durch Zustandslosigkeit<br />

entfällt diese Anforderung. Als Servicedesigner müssen Sie über Datenreplikation<br />

nur nachdenken, wenn Ihr Ressourcen-Zustand über mehrere Rechner<br />

verteilt werden muss.<br />

Repräsentationen<br />

Wenn Sie Ihre Anwendung in Ressourcen aufteilen, vergrößern Sie den Bereich, der<br />

nach außen hin sichtbar ist. Ihre Anwender können sich passende URIs bauen und in<br />

Ihre Anwendung genau dort einsteigen, wo sie es brauchen. Aber die Ressourcen<br />

sind nicht die Daten, sondern nur die Idee des Servicedesigners, wie die Daten in<br />

»eine Liste offener Bugs« oder »Informationen über Quallen« unterteilt werden. Ein<br />

Web-Server kann keine Ideen senden, er muss eine Abfolge von Bytes in einem<br />

bestimmten Dateiformat und einer bestimmten Sprache schicken. Das ist eine<br />

Repräsentation der Ressource.<br />

Eine Ressource ist eine Quelle für Repräsentationen, und eine Repräsentation<br />

besteht einfach aus Daten zum aktuellen Zustand einer Ressource. <strong>Die</strong> meisten Ressourcen<br />

sind selbst Daten (wie zum Beispiel eine Liste mit Fehlern), daher sind die<br />

Daten selbst eine offensichtliche Repräsentation einer Ressource. Der Server kann<br />

eine Liste mit ungelösten Fehlern als XML-Dokument, als Web-Seite oder als kommaseparierten<br />

Text ausgeben. <strong>Die</strong> Verkaufszahlen für das letzte Quartal 2004 können<br />

numerisch oder als Diagramm ausgegeben werden. Viele News-Sites stellen ihre<br />

Artikel in einem mit Werbung gespickten Format und in einem »druckerfreundlichen«<br />

reduzierten Format bereit. Es handelt sich immer um verschiedene Repräsentationen<br />

der gleichen Ressourcen.<br />

Max.<br />

Linie<br />

Repräsentationen | 103<br />

This is the Title of the Book, eMatter Edition<br />

Copyright © 2007 O’Reilly & Associates, Inc. All rights reserved.<br />

<strong>Die</strong>s ist ein Auszug aus dem Buch „Web Services mit REST“, ISBN 978-3-89721-727-0<br />

http://www.oreilly.de/catalog/restfulwsger/<br />

<strong>Die</strong>ser Auszug unterliegt dem Urheberrecht. © <strong>O'Reilly</strong> <strong>Verlag</strong> 2008


Aber manche Ressourcen repräsentieren physikalische Objekte oder andere Dinge,<br />

die nicht auf Informationen reduziert werden können. Was kann man da als gute<br />

Repräsentation verwenden? Sie müssen sich keine Sorgen um eine perfekte Widergabe<br />

machen: Eine Repräsentation ist jede nützliche Information über den Zustand<br />

einer Ressource.<br />

Stellen Sie sich ein physikalisches Objekt vor – z.B. einen Getränkeautomaten –, der<br />

mit einem Web Service verbunden ist. 5 Ziel ist, den Nutzern des Automaten<br />

unnötige Wege dorthin zu ersparen. Durch diesen Service können die Leute wissen,<br />

ob die Getränke kalt sind oder die bevorzugte Marke ausverkauft. Keiner erwartet,<br />

dass die realen Getränkedosen über den Web Service zur Verfügung stehen, da physische<br />

Objekte keine Daten sind. Aber es gibt Daten über sie: Metadaten. Jeder<br />

Schacht im Automaten kann mit einem Kästchen versehen werden, das über die<br />

Sorte, den Preis und die Temperatur der nächsten verfügbaren Dose Bescheid weiß.<br />

<strong>Die</strong> Metadaten dieser Geräte können in den Repräsentationen der Ressourcen verwendet<br />

werden.<br />

Selbst wenn eine der Repräsentationen eines Objekts die eigentlichen Daten enthält,<br />

kann es auch Repräsentationen geben, in denen sich Metadaten finden. Eine<br />

Onlinebuchhandlung kann zum Beispiel zwei Repräsentationen eines Buchs bereitstellen:<br />

1. Eine enthält nur Metadaten, wie zum Beispiel ein Bild des Titels und Reviews,<br />

mit denen das Buch beworben wird.<br />

2. Eine elektronische Variante der Daten im Buch, die Sie via HTTP erhalten,<br />

wenn Sie dafür zahlen.<br />

Repräsentationen funktionieren aber auch andersherum. Sie können eine Repräsentation<br />

einer neuen Ressource an den Server schicken, damit dort die Ressource<br />

erzeugt wird. Das geschieht, wenn Sie bei Flickr ein Bild hochladen. Oder Sie können<br />

dem Server eine neue Repräsentation einer bestehenden Ressource zukommen lassen<br />

und dadurch den Server die Ressource ändern lassen, damit sie mit der neuen<br />

Repräsentation im Einklang steht.<br />

Links<br />

Sich zwischen Repräsentationen entscheiden<br />

Wenn ein Server mehrere Repräsentationen einer Ressource anbietet, stellt sich die<br />

Frage, wie er herausfindet, nach welcher der Client fragt. So kann eine Pressemitteilung<br />

zum Beispiel sowohl auf Deutsch als auch auf Englisch veröffentlicht worden<br />

sein. Welche will ein bestimmter Client dann haben?<br />

Max.<br />

Linie<br />

5 <strong>Die</strong> Idee basiert auf dem CMU-Cola-Automaten (http://www.cs.cmu.edu/%7Ecoke/), der viele Jahre lang<br />

»beobachtet« wurde und dessen jeweiliger Status über das Finger-Protokoll abgefragt werden konnte.<br />

Der Automat existiert immer noch, allerdings war der Status <strong>beim</strong> Schreiben dieses Buchs nicht online<br />

abfragbar.<br />

Max.<br />

Linie<br />

104 | Kapitel 4: <strong>Die</strong> <strong>ressourcenorientierte</strong> <strong>Architektur</strong><br />

This is the Title of the Book, eMatter Edition<br />

Copyright © 2007 O’Reilly & Associates, Inc. All rights reserved.<br />

<strong>Die</strong>s ist ein Auszug aus dem Buch „Web Services mit REST“, ISBN 978-3-89721-727-0<br />

http://www.oreilly.de/catalog/restfulwsger/<br />

<strong>Die</strong>ser Auszug unterliegt dem Urheberrecht. © <strong>O'Reilly</strong> <strong>Verlag</strong> 2008


Rechts<br />

Es gibt eine Reihe von Möglichkeiten, das innerhalb der Grenzen von REST herauszufinden.<br />

Der einfachste – und die, die ich für die <strong>ressourcenorientierte</strong> <strong>Architektur</strong><br />

empfehle – ist ein eigener URI für jede Repräsentation einer Ressource. http://www.<br />

example.com/releases/104.de könnte für die deutsche Repräsentation der Pressemitteilung<br />

stehen und http://www.example.com/releases/104.en für die englische.<br />

Ich empfehle diese Technik für ROA-Anwendungen, weil der URI damit alle Informationen<br />

enthält, die der Server zum Beantworten des Requests benötigt. Der<br />

Nachteil bei der Bereitstellung von mehreren URIs für die gleiche Ressource ist eine<br />

Abschwächung: Leute, die über die Pressemitteilung in verschiedenen Sprachen<br />

reden, scheinen über unterschiedliche Dinge zu sprechen. Sie können das etwas<br />

abmildern, indem Sie den URI http://www.example.com/releases/104 anbieten, mit<br />

dem die Mitteilung in einer übergreifenden Form gemeint ist, unabhängig von einer<br />

Sprache.<br />

Eine Alternative wird als Content Negotiation bezeichnet. In diesem Szenario wird<br />

nur der übergreifende URI http://www.example.com/releases/104 veröffentlicht.<br />

Wenn ein Client einen Request für diesen URI abschickt, enthält er bestimmte<br />

HTTP-Request-Header, die anzeigen, was für eine Art von Repräsentation der Client<br />

akzeptieren wird.<br />

Ihr Web-Browser hat eine Einstellung für die Sprache: Dort können Sie festlegen, in<br />

welcher Sprache die Web-Seiten erscheinen sollen. Der Browser schickt diese Information<br />

mit jedem HTTP-Request im Header Accept-Language mit. Der Server ignoriert<br />

diese Information meist, da der Großteil der Web-Seiten nur in einer Sprache<br />

zur Verfügung steht. Aber es passt genau zu dem, was wir hier versuchen: Repräsentationen<br />

der gleichen Ressource in verschiedenen Sprachen bereitzustellen. Wenn<br />

ein Client http://www.example.com/releases/104 anfordert, kann der Server abhängig<br />

vom Header Accept-Language des Clients entscheiden, ob er die deutsche oder die<br />

englische Repräsentation ausliefert.<br />

<strong>Die</strong> Such-Engine von Google ist ein guter Ort, das auszuprobieren.<br />

Sie können Ihre Suchergebnisse in so gut wie jeder Sprache präsentiert<br />

bekommen, indem Sie die Spracheinstellungen Ihres Browsers<br />

ändern oder die Query-Variable hl in dem URI anpassen (zum Beispiel<br />

hl=tr für türkisch). <strong>Die</strong> Such-Engine unterstützt sowohl Content<br />

Negotiation als auch verschiedene URIs für unterschiedliche<br />

Repräsentationen.<br />

Max.<br />

Linie<br />

Ein Client kann auch den Header Accept setzen, um anzugeben, welches Dateiformat<br />

er für die Repräsentation bevorzugt. Er kann sagen, dass er lieber XHTML als<br />

HTML oder SVG als ein anderes Grafikformat haben möchte.<br />

Der Server kann alle diese Request-Metadaten nutzen, um zu entscheiden, welche<br />

Repräsentation er schickt. Andere mögliche Metadaten dazu sind Bezahlinformationen,<br />

Authentifizierungs-Credentials, der Zeitpunkt des Requests, Caching-<br />

Max.<br />

Linie<br />

Repräsentationen | 105<br />

This is the Title of the Book, eMatter Edition<br />

Copyright © 2007 O’Reilly & Associates, Inc. All rights reserved.<br />

<strong>Die</strong>s ist ein Auszug aus dem Buch „Web Services mit REST“, ISBN 978-3-89721-727-0<br />

http://www.oreilly.de/catalog/restfulwsger/<br />

<strong>Die</strong>ser Auszug unterliegt dem Urheberrecht. © <strong>O'Reilly</strong> <strong>Verlag</strong> 2008


Max.<br />

Linie<br />

Anweisungen und selbst die IP-Adresse des Clients. All diese Daten können in die<br />

Entscheidungsfindung des Servers einfließen, welche Daten in der Repräsentation<br />

enthalten sein sollen, welche Sprache und welches Format genutzt wird und sogar,<br />

ob überhaupt eine Repräsentation geschickt oder der Zugriff verweigert wird.<br />

Es ist REST-konform, diese Information in den HTTP-Headern zu speichern, und es<br />

ist auch REST-konform, sie in den URI zu stecken. Ich empfehle, so viele dieser<br />

Informationen wie möglich in den URI zu packen und so wenige wie möglich in die<br />

Metadaten des Requests. Ich denke, URIs sind nützlicher als Metadaten. URIs werden<br />

von Person zu Person und von Programm zu Programm weitergereicht. <strong>Die</strong><br />

Metadaten des Requests gehen dabei aber so gut wie immer verloren.<br />

Ein einfaches Beispiel für dieses Dilemma ist der W3C-HTML-Validator, ein Web<br />

Service, der unter http://validator.w3.org/ zur Verfügung steht. So sieht ein URI zu<br />

einer Ressource auf der Site des W3C aus, ein Validationsreport der deutschen Version<br />

meiner hypothetischen Pressemitteilung: http://validator.w3.org/check?uri=<br />

http%3A%2F%2Fwww.example.com%2Freleases%2F104.de.<br />

So sieht eine andere Ressource aus, ein Validationsreport der englischen Version der<br />

Pressemitteilung: http://validator.w3.org/check?uri=http%3A%2F%2Fwww.example.<br />

com%2Freleases%2F104.en.<br />

Jeder URI in Ihrem Web-Space wird zu einer Ressource in der Web-Anwendung des<br />

W3C, egal ob es zu einer eigenständigen Ressource auf Ihrer Site verweist. Wenn<br />

Ihre Pressemitteilung einen eigenen URI für jede Repräsentation hat, können Sie<br />

zwei Ressourcen vom W3C bekommen: Validationsreporte für die deutsche und die<br />

englische Version der Pressemitteilung.<br />

Aber wenn Sie nur die übergreifende Form des URI herausgeben und beide Repräsentationen<br />

über diesen URI anbieten, können Sie vom W3C nur eine Ressource bekommen.<br />

Das wäre ein Validationsreport für die Standardversion der Pressemitteilung<br />

(vermutlich die deutsche). Sie haben keine Möglichkeit herauszufinden, ob die<br />

englische Repräsentation HTML-Formatierungsfehler enthält. Wenn der Server die<br />

englische Pressemitteilung nicht als eigenen URI bereitstellt, gibt es keine entsprechende<br />

Ressource auf der W3C-Site. Das bedeutet nicht, dass Sie den übergreifenden<br />

URI nicht anbieten sollten – es sollte nur nicht der einzige URI sein, dene Sie nutzen.<br />

Anders als Menschen sind Computerprogramme sehr schlecht im Umgang mit<br />

Repräsentationen, die sie nicht erwarten. Ich denke, dass ein automatisierter Web-<br />

Client so explizit wie möglich sein sollte, wenn er die Repräsentation beschreibt, die er<br />

haben möchte. Das bedeutet so gut wie immer, dass sie in dem URI spezifiziert wird.<br />

Verweise und Verbindungshaftigkeit<br />

Manchmal sind Repräsentationen nicht viel mehr als serialisierte Datenstrukturen.<br />

Sie sind dazu gedacht, ihrer Daten beraubt und dann weggeworfen zu werden. Aber<br />

Links<br />

Max.<br />

Linie<br />

106 | Kapitel 4: <strong>Die</strong> <strong>ressourcenorientierte</strong> <strong>Architektur</strong><br />

This is the Title of the Book, eMatter Edition<br />

Copyright © 2007 O’Reilly & Associates, Inc. All rights reserved.<br />

<strong>Die</strong>s ist ein Auszug aus dem Buch „Web Services mit REST“, ISBN 978-3-89721-727-0<br />

http://www.oreilly.de/catalog/restfulwsger/<br />

<strong>Die</strong>ser Auszug unterliegt dem Urheberrecht. © <strong>O'Reilly</strong> <strong>Verlag</strong> 2008


Rechts<br />

in den meisten REST-konformen Services sind Repräsentationen Übermedien:<br />

Dokumente, die nicht nur Daten enthalten, sondern auch Verweise auf andere Ressourcen.<br />

Nehmen wir uns wieder das Suchbeispiel vor. Wenn Sie zu Googles Verzeichnis der<br />

Dokumente über Quallen gehen (http://www.google.com/search?q=Quallen), erhalten<br />

Sie ein paar Suchergebnisse und eine Reihe interner Verweise auf andere Seite<br />

des Verzeichnisses. Abbildung 4-3 zeigt einen passenden Ausschnitt aus der Seite.<br />

Teil des Verzeichnisses<br />

Max.<br />

Linie<br />

Abbildung 4-3: Ausschnitt einer Seite mit Suchergebnissen bei Google<br />

Interne Verzeichnis-Verweise<br />

Es gibt hier Daten und Verweise. <strong>Die</strong> Daten sagen aus, dass es irgendwo im Web<br />

irgendetwas gibt, das irgendwer über Quallen geschrieben hat. <strong>Die</strong> Verweise<br />

ermöglichen Ihnen Zugriff auf andere Ressourcen: manche innerhalb des »Web Service«<br />

von Google, andere irgendwo anders im Web:<br />

• <strong>Die</strong> externe Webseite, die sich mit Quallen befasst: http://de.wikipedia.org/wiki/<br />

Qualle. Hauptaufgabe dieses Web Service ist natürlich, solche Verweise zu präsentieren.<br />

• Ein Verweis auf einen von Google bereitgestellten Cache der externen Seite<br />

(der Verweis »Cached«). <strong>Die</strong>se Verweise haben immer lange URIs, die auf<br />

Google-eigene IP-Adressen zeigen, zum Beispiel http://209.85.135.104/search?q<br />

=cache:nZOeteMPBM...<br />

• Ein Verweis auf ein Verzeichnis mit Seiten, von denen Google denkt, dass sie<br />

zu der externen Seite in Beziehung stehen (http://www.google.com/search?hl=<br />

en&q=related:de.wikipedia.org/wiki/Qualle, bezeichnet als »Similar pages«).<br />

Das ist ein weiterer Fall eines Web Service, der einen URI als Eingabewert<br />

nutzt.<br />

• Eine Reihe von Navigationsverweisen, die Sie zu verschiedenen Seiten des<br />

Quallen-Verzeichnisses führen: http://www.google.com/search?q=Quallen&start<br />

=10, http://www.google.com/search?q=Quallen&start=20 und so weiter.<br />

Max.<br />

Linie<br />

Verweise und Verbindungshaftigkeit<br />

This is the Title of the Book, eMatter Edition<br />

| 107<br />

Copyright © 2007 O’Reilly & Associates, Inc. All rights reserved.<br />

<strong>Die</strong>s ist ein Auszug aus dem Buch „Web Services mit REST“, ISBN 978-3-89721-727-0<br />

http://www.oreilly.de/catalog/restfulwsger/<br />

<strong>Die</strong>ser Auszug unterliegt dem Urheberrecht. © <strong>O'Reilly</strong> <strong>Verlag</strong> 2008


Max.<br />

Linie<br />

Weiter oben in diesem Kapitel habe ich gezeigt, was passieren könnte, wenn HTTP<br />

ein zustandsbehaftetes Protokoll wie FTP wäre. Abbildung 4-2 zeigt den Weg, den<br />

ein zustandsbehafteter HTTP-Client während einer »Session« mit www.google.com<br />

nehmen könnte. HTTP funktioniert so natürlich nicht, aber die Abbildung zeigt<br />

ganz gut, wie wir das menschliche Web nutzen. Für die Nutzung einer Such-Engine<br />

beginnen wir auf der Homepage, tragen in ein Formular ihren Suchwunsch ein und<br />

klicken dann auf die Verweise, um die verschiedenen Ergebnisseiten zu erhalten. Wir<br />

tippen normalerweise nicht andauernd URIs ein – stattdessen folgen wir Verweisen<br />

und füllen Formulare aus.<br />

Wenn Sie schon vorher etwas über REST gelesen haben, ist Ihnen vielleicht ein<br />

Axiom aus der Dissertation von Fielding über den Weg gelaufen: »Übermedien als<br />

treibende Kraft des Anwendungszustands.« Das Axiom bedeutet, dass der aktuelle<br />

Zustand einer HTTP-»Session« nicht auf dem Server als Ressourcen-Zustand gespeichert,<br />

sondern vom Client als Anwendungszustand verfolgt und durch den Pfad<br />

erzeugt wird, den der Client im Web beschreitet. Der Server leitet den Client auf<br />

seinem Weg, indem er ihm »Übermedien« anbietet: Verweise und Formulare innerhalb<br />

einer Hypertext-Repräsentation.<br />

Der Server schickt dem Client Hilfestellungen, welche Zustände vom aktuellen aus<br />

gut erreicht werden können. Der Verweis »Next« auf http://www.google.com/<br />

search?q=Quallen ist ein Zustandswegweiser: Er zeigt Ihnen, wie Sie vom aktuellen<br />

Zustand zu einem damit verbundenen Zustand kommen. Das eröffnet viele Möglichkeiten.<br />

Ein Dokument, das einen URI enthält, verweist auf einen anderen möglichen<br />

Zustand der Anwendung: »Seite 2«, »Ähnlich wie dieser URI« oder »eine<br />

gecachete Version dieses URI«. Oder es verweist damit auf einen möglichen Zustand<br />

einer völlig anderen Anwendung.<br />

Ich nenne die Möglichkeit,Verweise zu enthalten, Verbindungshaftigkeit. Ein Web<br />

Service ist insoweit verbunden, als Sie den Service in verschiedene Zustände bringen<br />

können, indem Sie einfach Verweisen folgen und Formulare ausfüllen. Den Begriff<br />

»Verbindungshaftigkeit« nutze ich, weil »Übermedien als treibende Kraft des<br />

Anwendungszustands« das Konzept komplizierter klingen lässt als es ist. Ich will nur<br />

sagen, dass Ressourcen in ihren Repräsentationen miteinander verknüpft sein sollen.<br />

Das menschliche Web ist einfach zu nutzen, weil es so gut vernetzt ist. Jeder erfahrenere<br />

Anwender weiß, wie man URIs in die Adressleiste des Browsers eingibt und wie man auf<br />

einer Site herumspringen kann, indem man die URI verändert, aber viele Benutzer surfen<br />

im Web nur von einem einzigen Startpunkt aus: der Homepage des Browsers, die<br />

durch ihren ISP eingerichtet wurde. Das ist deshalb möglich, weil das Web so gut vernetzt<br />

ist. Seiten verweisen aufeinander, selbst über Site-Grenzen hinweg.<br />

<strong>Die</strong> meisten Web Services sind aber nicht einmal intern vernetzt, ganz zu schweigen<br />

von Verbindungen zu anderen Services. Amazon S3 ist ein REST-konformer Web<br />

Service, der adressierbar und zustandslos ist, aber nicht vernetzt. S3-Repräsenta-<br />

Links<br />

Max.<br />

Linie<br />

108 | Kapitel 4: <strong>Die</strong> <strong>ressourcenorientierte</strong> <strong>Architektur</strong><br />

This is the Title of the Book, eMatter Edition<br />

Copyright © 2007 O’Reilly & Associates, Inc. All rights reserved.<br />

<strong>Die</strong>s ist ein Auszug aus dem Buch „Web Services mit REST“, ISBN 978-3-89721-727-0<br />

http://www.oreilly.de/catalog/restfulwsger/<br />

<strong>Die</strong>ser Auszug unterliegt dem Urheberrecht. © <strong>O'Reilly</strong> <strong>Verlag</strong> 2008


Rechts<br />

tionen enthalten niemals URIs. Um ein S3-Bucket per GET zu erhalten, müssen Sie<br />

die Regeln kennen, wie der URI des Buckets aufgebaut wird. Sie können nicht einfach<br />

per GET die Bucket-Liste holen und dann einem Verweis zu dem Bucket folgen,<br />

das Sie brauchen.<br />

Beispiel 4-1 zeigt eine S3-Bucket-Liste, die ich geändert habe (durch ein zusätzliches<br />

Tag URI), damit sie verbindungsbehaftet ist. Vergleichen Sie das mit Beispiel 3-5, das<br />

kein solches Tag besitzt. Das ist nur eine Möglichkeit, URIs in eine XML-Repräsentation<br />

einzuführen. Wenn Ressourcen besser miteinander verbunden werden, werden<br />

auch die Beziehungen zwischen ihnen offensichtlicher (siehe Abbildung 4-4).<br />

Beispiel 4-1: Eine verbindungshaftige »Liste Ihrer Buckets«<br />

<br />

<br />

<br />

c0363f7260f2f5fcf38d48039f4fb5cab21b060577817310be5170e7774aad70<br />

leonardr28<br />

<br />

<br />

<br />

crummy.com<br />

https://s3.amazonaws.com/crummy.com<br />

2006-10-26T18:46:45.000Z<br />

<br />

<br />

<br />

Max.<br />

Linie<br />

a b c<br />

Alle drei Services bieten die gleiche Funktionalität an, aber ihr Nutzen steigert sich von links nach rechts.<br />

• Service A ist ein typischer Service im RPC-Stil, denn alles wird über eine einzelne URI angeboten.<br />

Er ist weder adressierbar noch verbunden.<br />

• Service B ist adressierbar, aber nicht verbunden: Es gibt keine Hinweise auf die Beziehungen zwischen<br />

den Ressourcen. Das kann ein REST-RPC-Hybrid sein oder ein REST-konformer Service wie Amazon S3.<br />

• Service C ist adressierbar und gut verbunden: Ressourcen sind (vermutlich) sinnvoll miteinander<br />

verknüpft. Das könnte ein vollständiger REST-konformer Service sein.<br />

Abbildung 4-4: Ein Service auf drei Wegen<br />

Max.<br />

Linie<br />

Verweise und Verbindungshaftigkeit<br />

This is the Title of the Book, eMatter Edition<br />

| 109<br />

Copyright © 2007 O’Reilly & Associates, Inc. All rights reserved.<br />

<strong>Die</strong>s ist ein Auszug aus dem Buch „Web Services mit REST“, ISBN 978-3-89721-727-0<br />

http://www.oreilly.de/catalog/restfulwsger/<br />

<strong>Die</strong>ser Auszug unterliegt dem Urheberrecht. © <strong>O'Reilly</strong> <strong>Verlag</strong> 2008


Max.<br />

Linie<br />

<strong>Die</strong> einheitliche Schnittstelle<br />

Im ganzen Web gibt es nur ein paar Dinge, die Sie mit einer Ressource anstellen können.<br />

HTTP stellt vier grundlegende Methoden für die gebräuchlichsten Operationen<br />

bereit:<br />

• eine Repräsentation einer Ressource holen: HTTP GET<br />

• eine neue Ressource erstellen: HTTP PUT an einen neuen URI oder HTTP<br />

POST an eine bestehende (siehe den Abschnitt »POST« auf Seite 112)<br />

• eine bestehende Ressource verändern: HTTP PUT an einen bestehenden URI<br />

• eine bestehende Ressource löschen: HTTP DELETE<br />

Ich werde erläutern, wie diese vier Methoden verwendet werden, um jede Operation<br />

darzustellen, die Sie sich vorstellen können. Ich werde auch zwei HTTP-Methoden<br />

für weniger gebräuchliche Operationen vorstellen: HEAD und OPTIONS.<br />

GET, PUT und DELETE<br />

<strong>Die</strong>se drei sollten Ihnen noch vom S3-Beispiel in Kapitel 3 vertraut sein. Um eine<br />

Ressource zu holen oder zu löschen, schickt der Client einfach einen GET- oder<br />

DELETE-Request an den entsprechenden URI. Im Fall eines GET-Requests schickt<br />

der Server eine Repräsentation im Entity-Body der Response zurück. Bei einem<br />

DELETE-Request kann der Entity-Body eine Statusmitteilung oder auch gar nichts<br />

enthalten.<br />

Um eine Ressource zu erstellen oder zu verändern, schickt der Client einen PUT-<br />

Request, der normalerweise einen Entity-Body enthält. Dazu gehört die vom Client<br />

vorgeschlagene neue Repräsentation der Ressource. Welche Daten das sind und wie<br />

sie formatiert sind, hängt vom Service ab. Egal wie sie aussehen – dies ist die Stelle,<br />

an der der Anwendungszustand zum Server wandert und ein Ressourcen-Zustand<br />

wird.<br />

Schauen wir uns wieder den S3-Service an, in dem Sie zwei Arten von Ressourcen<br />

erstellen können: Buckets und Objekte. Um ein Objekt anzulegen, schicken Sie<br />

einen PUT-Request an seinen URI und übergeben den Inhalt des Objekts im Entity-<br />

Body Ihres Requests. Dasselbe machen Sie, um ein Objekt zu verändern: Der neue<br />

Inhalt überschreibt jeden vorhandenen alten.<br />

Das Erstellen eines Buckets läuft ein wenig anders ab, da Sie keinen Entity-Body im<br />

PUT-Request angeben müssen. Ein Bucket hat abgesehen von seinem Namen keinen<br />

Ressourcen-Zustand, und der Name ist Teil des URI. (Das ist nicht ganz korrekt. <strong>Die</strong><br />

Objekte in einem Bucket sind auch Elemente des Ressourcen-Zustands dieses Buckets,<br />

denn sie werden aufgelistet, wenn Sie die Repräsentation eines Buckets per GET<br />

holen. Aber jedes S3-Objekt ist eine Ressource für sich, daher gibt es keinen Grund,<br />

ein Objekt über sein Bucket zu verändern. Jedes Objekt bietet die einheitliche<br />

Links<br />

Max.<br />

Linie<br />

110 | Kapitel 4: <strong>Die</strong> <strong>ressourcenorientierte</strong> <strong>Architektur</strong><br />

This is the Title of the Book, eMatter Edition<br />

Copyright © 2007 O’Reilly & Associates, Inc. All rights reserved.<br />

<strong>Die</strong>s ist ein Auszug aus dem Buch „Web Services mit REST“, ISBN 978-3-89721-727-0<br />

http://www.oreilly.de/catalog/restfulwsger/<br />

<strong>Die</strong>ser Auszug unterliegt dem Urheberrecht. © <strong>O'Reilly</strong> <strong>Verlag</strong> 2008


Rechts<br />

Schnittstelle an, und sie können es separat anpassen.) Legen Sie denURI des Buckets<br />

fest, spezifizieren Sie damit auch seine Repräsentation. PUT-Requests enthalten für<br />

die meisten Ressourcen einen Entity-Body mit einer Repräsentation, aber wie Sie<br />

sehen, ist dies nicht zwingend erforderlich.<br />

HEAD und OPTIONS<br />

Es gibt drei andere HTTP-Methoden, die ich als Teil der einheitlichen Schnittstelle<br />

betrachte. Zwei davon sind einfache Hilfsmethoden, daher werde ich sie als Erstes<br />

behandeln.<br />

• nur die Repräsentation der Metadaten holen: HTTP HEAD<br />

• prüfen, welche HTTP-Methoden eine bestimmte Ressource unterstützt: HTTP<br />

OPTIONS<br />

Sie haben die Methode HEAD schon bei den S3-Service-Ressourcen in Kapitel 3 in<br />

Aktion gesehen. Ein S3-Client nutzt HEAD, um Metadaten zu einer Ressource zu<br />

holen, ohne den eventuell enorm großen Entity-Body laden zu müssen. Genau dafür<br />

ist HEAD gedacht. Ein Client kann HEAD verwenden, um zu prüfen, ob eine Ressource<br />

existiert, oder andere Informationen über sie erhalten, ohne ihre gesamte<br />

Repräsentation zu holen. HEAD gibt Ihnen genau das zurück, was auch GET liefern<br />

würde, aber ohne den Entity-Body.<br />

Es gibt zwei Standard-HTTP-Methoden, die ich in diesem Buch<br />

nicht behandeln werde: TRACE und CONNECT. TRACE wird<br />

genutzt, um Proxies zu debuggen, während man CONNECT verwendet,<br />

um ein anderes Protokoll über einen HTTP-Proxy weiterzuleiten.<br />

Max.<br />

Linie<br />

<strong>Die</strong> Methode OPTIONS ermöglicht dem Client herauszufinden, was man mit einer<br />

Ressource anstellen kann. <strong>Die</strong> Response auf einen OPTIONS-Request enthält den<br />

HTTP-Header Allow, der die Untermenge der einheitlichen Schnittstelle angibt, die<br />

von dieser Ressource unterstützt wird. Hier ein Beispiel-Header:<br />

Allow: GET, HEAD<br />

Aufgrund dieses Headers kann der Client davon ausgehen, dass der Server auf GEToder<br />

HEAD-Requests für diese Ressource sinnvoll reagiert, aber keine anderen<br />

HTTP-Methoden unterstützt werden. <strong>Die</strong>se Ressource ist also nur lesend ansprechbar.<br />

<strong>Die</strong> Header, die der Client im Request schickt, können eventuell den Header Allow<br />

verändern, den der Server als Reaktion zurückschickt. Wenn Sie zum Beispiel einen<br />

passenden Authorization-Header mit einem OPTIONS-Request senden, kann es<br />

sein, dass Sie GET-, HEAD-, PUT- und DELETE-Requests für einen bestimmten<br />

URI schicken dürfen. Senden Sie den gleichen OPTIONS-Request, lassen aber den<br />

Max.<br />

Linie<br />

<strong>Die</strong> einheitliche Schnittstelle<br />

This is the Title of the Book, eMatter Edition<br />

| 111<br />

Copyright © 2007 O’Reilly & Associates, Inc. All rights reserved.<br />

<strong>Die</strong>s ist ein Auszug aus dem Buch „Web Services mit REST“, ISBN 978-3-89721-727-0<br />

http://www.oreilly.de/catalog/restfulwsger/<br />

<strong>Die</strong>ser Auszug unterliegt dem Urheberrecht. © <strong>O'Reilly</strong> <strong>Verlag</strong> 2008


Header Authorization weg, ist Ihnen vielleicht nur GET und HEAD gestattet. <strong>Die</strong><br />

Methode OPTIONS ermöglicht dem Client, einfache Zugriffskontrollprüfungen<br />

vorzunehmen.<br />

Theoretisch kann der Server zusätzliche Informationen als Response auf einen<br />

OPTIONS-Request schicken und der Client kann OPTIONS-Requests senden, die<br />

den Server zu spezifischen Möglichkeiten befragen. Schön und gut, nur leider kein<br />

akzeptierter Standard in Bezug auf das, was ein Client in einem OPTIONS-Request<br />

fragen darf. Neben dem Header Allow gibt es keine akzeptierten Standards, was ein<br />

Server als Response schicken könnte. <strong>Die</strong> meisten Web-Server und Frameworks<br />

unterstützen OPTIONS nur sehr eingeschränkt. Bisher ist OPTIONS nur eine vielversprechende<br />

Idee, die niemand verwendet.<br />

Links<br />

Max.<br />

Linie<br />

POST<br />

Nun kommen wir zur am meisten missverstandenen HTTP-Methode: POST. <strong>Die</strong>se<br />

Methode hat prinzipiell zwei Funktionen: eine, die innerhalb der Grenzen von REST<br />

liegt, und eine, die sich außerhalb befindet und ein Element im RPC-Stil einführt. In<br />

komplexen Fällen wie diesem ist es am besten, auf den Originaltext zurückzugreifen.<br />

Folgendes sagt RFC 2616, der HTTP-Standard, über POST (aus dem Abschnitt 9.5):<br />

POST wurde entworfen, um eine einheitliche Methode für folgende Funktionen zu<br />

bieten:<br />

• Kommentieren bestehender Ressourcen<br />

• Posten einer Nachricht an ein Bulletin Board, eine Newsgroup, eine Mailing-Liste<br />

oder ähnliche Artikelsammlungen<br />

• Bereitstellen von Daten wie zum Beispiel dem Ergebnis eines Formular-Submits an<br />

einen datenverarbeitenden Prozess<br />

• Erweitern einer Datenbank durch eine Append-Operation<br />

<strong>Die</strong> tatsächlich durch POST ausgeführte Funktion wird durch den Server bestimmt<br />

und hängt normalerweise von dem Request-URI ab. <strong>Die</strong> gepostete Entität ist diesem<br />

URI genauso untergeordnet, wie eine Datei einem Verzeichnis untergeordnet ist, in<br />

dem sie liegt, ein News-Artikel einer Newsgroup, in der er gepostet wurde, oder ein<br />

Datensatz einer Datenbank.<br />

Was bedeutet das im Kontext von REST und der ROA?<br />

Untergeordnete Ressourcen erstellen<br />

In einem REST-konformen Design wird POST häufig verwendet, um untergeordnete<br />

Ressourcen zu erzeugen, also solche, die in Beziehung zu anderen »Eltern«-Ressourcen<br />

stehen. Ein Weblog-Programm könnte zum Beispiel jedes Weblog als Ressource<br />

bereitstellen (/weblogs/myweblog) und die einzelnen Weblog-Einträge als untergeordnete<br />

Ressourcen (/weblogs/myweblog/entries/1). Eine Datenbank mit Web-<br />

Anschluss mag eine Tabelle als Ressource bereitstellen und die einzelnen Daten-<br />

Max.<br />

Linie<br />

112 | Kapitel 4: <strong>Die</strong> <strong>ressourcenorientierte</strong> <strong>Architektur</strong><br />

This is the Title of the Book, eMatter Edition<br />

Copyright © 2007 O’Reilly & Associates, Inc. All rights reserved.<br />

<strong>Die</strong>s ist ein Auszug aus dem Buch „Web Services mit REST“, ISBN 978-3-89721-727-0<br />

http://www.oreilly.de/catalog/restfulwsger/<br />

<strong>Die</strong>ser Auszug unterliegt dem Urheberrecht. © <strong>O'Reilly</strong> <strong>Verlag</strong> 2008


Rechts<br />

Max.<br />

Linie<br />

bankzeilen als deren untergeordnete Ressourcen. Um einen Weblog-Eintrag oder<br />

eine Datenbankzeile zu erzeugen, schicken Sie ein POST an das Eltern-Element: das<br />

Weblog oder die Datenbanktabelle. Was für Daten Sie posten, und in welchem Format,<br />

hängt vom Service ab, aber wie bei PUT ist dies der Moment, in dem ein<br />

Anwendungszustand ein Ressourcen-Zustand wird. Sie können diese Verwendung<br />

von POST als POST(a) bezeichnen, für »Anhängen«. Wenn ich in diesem Buch<br />

»POST« schreibe, meine ich so gut wie immer POST(a).<br />

Warum können Sie nicht einfach PUT verwenden, um untergeordnete Ressourcen<br />

zu erstellen? Nun, manchmal können Sie das. Ein S3-Objekt ist eine untergeordnete<br />

Ressource, denn jedes S3-Objekt ist in einem S3-Bucket enthalten. Aber wir erstellen<br />

kein S3-Objekt, indem wir einen POST-Request an das Bucket schicken. Wir senden<br />

ein PUT direkt an den URI des Objekts. Der Unterschied zwischen PUT und POST<br />

ist dieser: Der Client nutzt PUT, wenn er dafür verantwortlich ist zu entscheiden,<br />

welchen URI die neue Ressource bekommen soll. Er nutzt POST, wenn der Server<br />

die Entscheidung über den URI der neuen Ressource fällen soll.<br />

Der S3-Service erwartet, dass Clients S3-Objekte mit PUT anlegen, da der URI eines<br />

S3-Objekts vollständig durch seinen Namen und den des Buckets festgelegt wird.<br />

Wenn der Client genug darüber weiß, wie das Objekt anzulegen ist, weiß er auch,<br />

wie der URI lauten wird. Der offensichtliche URI, der als Ziel des PUT-Requests verwendet<br />

wird, ist der, der das Bucket nutzen wird, sobald er existiert.<br />

Aber stellen Sie sich eine Anwendung vor, in der der Server mehr Kontrolle über die<br />

URIs hat, zum Beispiel ein Weblog-Programm. Der Client kann alle Informationen<br />

sammeln, die notwendig sind, um einen Weblog-Eintrag zu erstellen, und trotzdem<br />

nicht wissen, welchen URI der Eintrag haben wird, nachdem er einmal angelegt<br />

wurde. Vielleicht basieren die vom Server erstellten URIs auf der Reihenfolge einer<br />

internen Datenbank-ID: Wird der fertige URI /weblogs/myweblog/entries/1 oder<br />

/weblogs/myweblog/entries/1000 lauten? Vielleicht basiert der endgültige URI auf<br />

dem Zeitpunkt der Veröffentlichung: Von welcher Zeit geht der Server aus? Der<br />

Client sollte solche Dinge nicht wissen müssen.<br />

<strong>Die</strong> POST-Methode ist eine Möglichkeit, neue Ressourcen zu erstellen, ohne dass<br />

der Client den genauen URI wissen muss. In den meisten Fällen benötigt der Client<br />

nur den URI einer »Eltern«- oder »Fabrik«-Ressource. Der Server holt sich die<br />

Repräsentation aus dem Entity-Body und verwendet sie, um eine neue Ressource<br />

»unterhalb« der »Eltern«-Ressource anzulegen (die Bedeutung von »unterhalb«<br />

hängt vom Kontext ab).<br />

<strong>Die</strong> Response auf diese Art von POST-Requests hat normalerweise einen HTTP-Statuscode<br />

201 (»Created«). Sein Header Location enthält den URI der neu erstellten<br />

untergeordneten Ressource. Nachdem die Ressource nun tatsächlich existiert und<br />

der Client ihren URI kennt, können zukünftige Requests die PUT-Methode ver-<br />

Max.<br />

Linie<br />

<strong>Die</strong> einheitliche Schnittstelle<br />

This is the Title of the Book, eMatter Edition<br />

| 113<br />

Copyright © 2007 O’Reilly & Associates, Inc. All rights reserved.<br />

<strong>Die</strong>s ist ein Auszug aus dem Buch „Web Services mit REST“, ISBN 978-3-89721-727-0<br />

http://www.oreilly.de/catalog/restfulwsger/<br />

<strong>Die</strong>ser Auszug unterliegt dem Urheberrecht. © <strong>O'Reilly</strong> <strong>Verlag</strong> 2008


wenden, um diese Ressource zu verändern, mit GET eine Repräsentation davon<br />

holen und sie mit DELETE löschen.<br />

Tabelle 4-1 zeigt, wie ein PUT-Request an einen URI die zugrundeliegende Ressource<br />

erstellen oder verändern kann, und wie ein POST-Request an denselben URI eine<br />

neue, untergeordnete Ressource erzeugen kann.<br />

Links<br />

Tabelle 4-1: PUT-Aktionen<br />

/weblogs<br />

PUT an eine neue<br />

Ressource<br />

– (Ressource besteht<br />

bereits)<br />

PUT an eine bestehende<br />

Ressource<br />

Kein Effekt<br />

/weblogs/myweblog Erstelle dieses Weblog Verändere die Einstellungen<br />

dieses Weblogs<br />

/weblogs/myweblog/<br />

entries/1<br />

– (wie würden Sie zu diesem<br />

URI kommen?)<br />

<strong>Die</strong>sen Weblog-Eintrag<br />

verändern<br />

POST<br />

Erstelle ein neues Weblog<br />

Erstelle einen neuen<br />

Weblog-Eintrag<br />

Einen Kommentar zu diesem<br />

Weblog-Eintrag<br />

posten<br />

Max.<br />

Linie<br />

An den Ressourcen-Zustand anhängen<br />

<strong>Die</strong> Informationen, die in einem POST an eine Ressource transportiert werden, müssen<br />

nicht zu einer komplett neuen, untergeordneten Ressource führen. Manchmal<br />

werden die Daten bei einem POST an eine Ressource an ihren eigenen Zustand angehängt,<br />

anstatt sie in eine neue Ressource zu stecken.<br />

Stellen Sie sich einen Ereignisprotokollservice vor, der eine einzige Ressource bereitstellt:<br />

das Log. Nehmen wir an, sein URI wäre /log. Um das Log zu holen, schicken<br />

Sie einen GET-Request an /log.<br />

Wie soll nun ein Client etwas an das Log anhängen? Er könnte einen PUT-Request<br />

an /log schicken, aber die PUT-Methode ist eigentlich dazu gedacht, eine neue Ressource<br />

zu erstellen oder alte Einstellungen durch neue zu überschreiben. Der Client<br />

will aber beides nicht, sondern nur Informationen an das Ende des Logs anhängen.<br />

<strong>Die</strong> POST-Methode passt hier, so als ob jeder Log-Eintrag als eigenständige Ressource<br />

bereitgestellt würde. <strong>Die</strong> Semantik von POST ist in beiden Fällen gleich: Der Client<br />

fügt einer bestehenden Ressource untergeordnete Informationen hinzu. Der einzige<br />

Unterschied liegt darin, dass <strong>beim</strong> Weblog und seinen Einträgen die untergeordneten<br />

Informationen als neue Ressourcen erscheinen. Hier taucht die untergeordnete<br />

Information als neues Datenelement in der Repräsentation des Eltern-Elements<br />

auf.<br />

Überladenes POST: <strong>Die</strong> nicht so einheitliche Schnittstelle<br />

<strong>Die</strong>se Art, die Sache zu betrachten, erklärt einen Großteil dessen, was der HTTP-<br />

Standard über POST sagt. Sie können es verwenden, um Ressourcen unterhalb einer<br />

Max.<br />

Linie<br />

114 | Kapitel 4: <strong>Die</strong> <strong>ressourcenorientierte</strong> <strong>Architektur</strong><br />

This is the Title of the Book, eMatter Edition<br />

Copyright © 2007 O’Reilly & Associates, Inc. All rights reserved.<br />

<strong>Die</strong>s ist ein Auszug aus dem Buch „Web Services mit REST“, ISBN 978-3-89721-727-0<br />

http://www.oreilly.de/catalog/restfulwsger/<br />

<strong>Die</strong>ser Auszug unterliegt dem Urheberrecht. © <strong>O'Reilly</strong> <strong>Verlag</strong> 2008


Rechts<br />

Max.<br />

Linie<br />

Eltern-Ressource zu erstellen oder um zusätzliche Daten an den aktuellen Zustand<br />

einer Ressource anzuhängen. <strong>Die</strong> eine Verwendung von POST, die ich bisher nicht<br />

erklärt habe, ist die, mit der Sie vermutlich am besten vertraut sind, da damit so gut<br />

wie alle Web-Anwendungen arbeiten: das Liefern von Daten, wie zum Beispiel dem<br />

Ergebnis eines abgeschickten Formulars, an einen datenverarbeitenden Prozess.<br />

Was ist ein »datenverarbeitender Prozess«? Das kling ziemlich vage. Und tatsächlich<br />

kann so gut wie alles ein datenverarbeitender Prozess sein. Verwendet man POST auf<br />

diese Art und Weise, verwandelt man eine Ressource in einen kleinen Nachrichtenprozessor,<br />

der sich wie ein XML-RPC-Server verhält. <strong>Die</strong> Ressource akzeptiert einen<br />

POST-Request, begutachtet ihn und entscheidet sich dazu, irgendetwas zu tun.<br />

Dann entscheidet er sich dazu, dem Client irgendwelche Daten zu liefern.<br />

Ich bezeichne diese Verwendung von POST als überladenes POST, in Analogie zum<br />

Überladen von Operatoren in einer Programmiersprache. Es ist überladen, weil eine<br />

einzelne HTTP-Methode verwendet wird, um für viele Nicht-HTTP-Methoden zu<br />

stehen. Es ist aus dem gleichen Grund verwirrend, wie das Überladen von Operatoren<br />

verwirrend sein kann: Sie dachten, Sie wüssten, was HTTP-POST tut, aber nun<br />

wird es verwendet, um einem unbekannten Zweck zu dienen. Sie könnten das überladene<br />

POST als POST(p) bezeichnet finden – für »prozessiert«.<br />

Wenn Ihr Service überladenes POST bereitstellt, kommt wieder die Frage auf:<br />

»Warum sollte der Server dies tun statt jenes?« Jeder HTTP-Request muss Methodeninformationen<br />

enthalten, und wenn Sie überladenes POST verwenden, kann dies<br />

nicht in der HTTP-Methode geschehen. <strong>Die</strong> POST-Methode ist nur eine Direktive an<br />

den Server, die sagt: »Schau in den HTTP-Request, um die eigentliche Methoden-<br />

Information zu erhalten.« <strong>Die</strong> eigentliche Information kann in dem URI, den HTTP-<br />

Headern oder dem Entity-Body enthalten sein. Wie auch immer die Sache vor sich<br />

geht – ein bisschen RPC-Stil ist auf jeden Fall in den Service gesickert.<br />

Wenn sich die Methoden-Information nicht in der HTTP-Methode befindet, ist die<br />

Schnittstelle nicht mehr einheitlich. <strong>Die</strong> eigentliche Methoden-Information kann<br />

sonstwo sein. Als REST-Partisane mag ich das nicht wirklich, aber manchmal lässt es<br />

sich nicht vermeiden. Bis Kapitel 9 werden Sie gesehen haben, wie so gut wie jedes<br />

denkbare Szenario über die einheitliche Schnittstelle von HTTP zu verwirklichen ist,<br />

aber manchmal ist der RPC-Stil der einfachste Weg, um komplexe Operationen auszudrücken,<br />

die mehrere Ressourcen umfassen.<br />

Eventuell müssen Sie überladenes POST bereitstellen, auch wenn Sie POST nur<br />

nutzen, um untergeordnete Ressourcen anzulegen oder an eine Repräsentation einer<br />

Ressource anzuhängen. Was sollte man zum Beispiel tun, wenn eine einzelne Ressource<br />

beide Arten von POST unterstützt? Woher weiß der Server, ob ein Client ein<br />

POST abschickt, um eine untergeordnete Ressource zu erzeugen oder um an die<br />

bestehende Repräsentation der Ressourcen anzuhängen? Sie müssen vielleicht<br />

irgendwo im HTTP-Request zusätzliche Methoden-Informationen angeben.<br />

Max.<br />

Linie<br />

<strong>Die</strong> einheitliche Schnittstelle<br />

This is the Title of the Book, eMatter Edition<br />

| 115<br />

Copyright © 2007 O’Reilly & Associates, Inc. All rights reserved.<br />

<strong>Die</strong>s ist ein Auszug aus dem Buch „Web Services mit REST“, ISBN 978-3-89721-727-0<br />

http://www.oreilly.de/catalog/restfulwsger/<br />

<strong>Die</strong>ser Auszug unterliegt dem Urheberrecht. © <strong>O'Reilly</strong> <strong>Verlag</strong> 2008


Überladenes POST sollte nicht verwendet werden, um ein schlechtes Ressourcendesign<br />

zu verdecken. Denken Sie daran, dass eine Ressource so gut wie alles sein kann.<br />

Normalerweise ist es möglich, Ihr Ressourcendesign so zu verändern, dass die einheitliche<br />

Schnittstelle passt, anstatt den RPC-Stil in Ihren Service einzuführen.<br />

Links<br />

Max.<br />

Linie<br />

Sicherheit und Idempotenz<br />

Wenn Sie die uniforme Schnittstelle von HTTP so bereitstellen wollen, wie sie<br />

entworfen wurde, erhalten Sie zwei nützliche Eigenschaften kostenlos dazu. Verwendet<br />

man sie korrekt, sind GET- und HEAD-Requests sicher. Requests mit GET,<br />

HEAD, PUT und DELETE sind zudem idempotent.<br />

Sicherheit<br />

Ein GET- oder HEAD-Request ist eine Anfrage, um bestimmte Daten zu lesen, keine<br />

Anfrage, irgendwelche Serverzustände zu ändern. Der Client kann einen GET- oder<br />

HEAD-Request zehn Mal hintereinander ausführen und es wäre so, als ob er nur einmal<br />

oder niemals gesendet worden wäre. Wenn Sie per GET http://www.google.com/<br />

search?q=Quallen anfordern, ändern Sie nichts im Verzeichnis der Ressourcen über<br />

Quallen. Sie holen einfach nur eine Repräsentation davon ab. Ein Client sollte in der<br />

Lage sein, einen GET- oder HEAD-Request an einen unbekannten URI zu schicken,<br />

ohne sich Sorgen machen zu müssen, ob etwas zerstört wird.<br />

Das heißt nicht, dass GET- und HEAD-Requests keine Nebeneffekte haben können.<br />

Manche Ressourcen führen Zähler, die bei jedem Zugriff eines Clients per GET<br />

erhöht werden. <strong>Die</strong> meisten Web-Server protokollieren jeden eingehenden Request<br />

in einer Log-Datei. Das sind Nebeneffekte: Der Server-Zustand und sogar der Ressourcen-Zustand<br />

werden als Reaktion auf einen GET-Request geändert. Aber der<br />

Client hat nicht darum gebeten und ist dafür auch nicht verantwortlich. Ein Client<br />

sollte niemals einen GET- oder HEAD-Request nur aufgrund der Nebeneffekte ausführen,<br />

und die Nebeneffekte sollten auch niemals so stark sein, dass der Client sich<br />

wünschte, er hätte den Request niemals abgeschickt.<br />

Idempotenz<br />

Idempotenz ist etwas trickreicher. <strong>Die</strong> Idee kommt aus der Mathematik, und wenn<br />

Sie mit Idempotenz nicht vertraut sind, kann ein mathematisches Beispiel vielleicht<br />

helfen. Eine idempotente Operation in der Mathematik ist eine, die bei einmaliger<br />

Anwendung denselben Effekt hat wie bei mehrfacher. Das Multiplizieren einer Zahl<br />

mit Null ist idempotent: 4 × 0 × 0 × 0 ist das Gleiche wie 4 × 0. 6 Analog dazu ist eine<br />

Operation auf einer Ressource idempotent, wenn das Abschicken eines Requests das<br />

6 Das Multiplizieren einer Zahl mit 1 ist sowohl sicher als auch idempotent: 4 × 1 × 1 × 1 ist das Gleiche<br />

wie 4 ×1, ergibt nämlich 4. <strong>Die</strong> Multiplikation mit Null ist nicht sicher, da 4 × 0 nicht das Gleiche wie<br />

4 ist. Das Multiplizieren mit jeder anderen Zahl ist weder sicher noch idempotent.<br />

Max.<br />

Linie<br />

116 | Kapitel 4: <strong>Die</strong> <strong>ressourcenorientierte</strong> <strong>Architektur</strong><br />

This is the Title of the Book, eMatter Edition<br />

Copyright © 2007 O’Reilly & Associates, Inc. All rights reserved.<br />

<strong>Die</strong>s ist ein Auszug aus dem Buch „Web Services mit REST“, ISBN 978-3-89721-727-0<br />

http://www.oreilly.de/catalog/restfulwsger/<br />

<strong>Die</strong>ser Auszug unterliegt dem Urheberrecht. © <strong>O'Reilly</strong> <strong>Verlag</strong> 2008


Rechts<br />

Max.<br />

Linie<br />

Gleiche ist wie das Abschicken einer ganzen Serie identischer Requests. Der zweite<br />

und folgende Requests belassen den Ressourcen-Zustand in exakt dem gleichen<br />

Zustand wie er durch den ersten Request entstanden ist.<br />

PUT- und DELETE-Operationen sind idempotent. Wenn Sie eine Ressource per<br />

DELETE löschen, ist sie weg. Wenn Sie DELETE erneut abfeuern, bleibt sie verschwunden.<br />

Wenn Sie eine neue Ressource mit PUT anlegen und dann PUT nochmals<br />

abschicken, ist die Ressource immer noch da und hat auch die gleichen<br />

Eigenschaften wie nach dem ersten PUT. Wenn Sie PUT verwenden, um den<br />

Zustand einer Ressource zu ändern, können Sie den PUT-Request nochmals senden,<br />

ohne dass sich der Ressourcen-Zustand ändern wird.<br />

Ein zu beachtender Punkt ist daher, dass Sie Ihren Clients nicht erlauben sollten,<br />

Repräsentationen per PUT zu übermitteln, die einen Ressourcenstatus mit relativen<br />

Werten ändern. Wenn eine Ressource einen numerischen Wert als Teil ihres<br />

Zustands enthält, kann ein Client vielleicht PUT nutzen, um den Wert auf 4 oder 0<br />

oder -50 zu setzen, aber nicht, um den Wert um 1 zu erhöhen. Wenn der ursprüngliche<br />

Wert 0 ist und man zwei PUT-Requests schickt, die sagen: »Setze den Wert auf<br />

4«, bleibt der Wert auf 4. Wenn der Anfangswert 0 ist und man zwei PUT-Requests<br />

schickt, die sagen »Erhöhe den Wert um 1«, wird der Wert danach nicht 1, sondern<br />

2 sein. Das ist nicht idempotent.<br />

Warum Sicherheit und Idempotenz wichtig sind<br />

Sicherheit und Idempotenz ermöglichen einem Client, zuverlässige HTTP-Requests<br />

über ein unzuverlässiges Netzwerk zu versenden. Wenn Sie einen GET-Request<br />

abschicken und keine Response erhalten, feuern Sie ihn einfach nochmals ab. Er ist<br />

sicher: Selbst wenn Ihr erster Request angekommen war, hatte er keinen echten<br />

Effekt auf den Server. Wenn Sie einen PUT-Request machen und keine Response<br />

erhalten, schicken Sie ihn nochmals los. Wenn Ihr erster Request durchgekommen<br />

ist, wird ein zweiter keinen zusätzlichen Effekt haben.<br />

POST ist weder sicher noch idempotent. Das Abschicken zweier identischer POST-<br />

Requests an eine »Fabrik«-Ressource wird vermutlich in zwei untergeordneten Ressourcen<br />

enden, die beide die gleichen Informationen enthalten. Bei überladenem<br />

POST kann man gar nicht mehr sagen, was passieren wird.<br />

Der häufigste Missbrauch der einheitlichen Schnittstelle ist, unsichere Operationen<br />

per GET verfügbar zu machen. Sowohl del.icio.us als auch die Flickr-API tun dies.<br />

Wenn Sie per GET https://api.del.icio.us/posts/delete aufrufen, erhalten Sie keine<br />

Repräsentation – stattdessen verändern Sie den Datensatz bei del.icio.us.<br />

Warum ist das schlecht? Nun, dazu eine kleine Geschichte. Im Jahr 2005 veröffentlichte<br />

Google ein Caching-Tool für den Client namens Web Accelerator. Es lief<br />

zusammen mit dem Web-Browser und holte die Seiten im Voraus, die auf der aktuell<br />

betrachteten Seite einen Verweis hatten. Wenn man dann auf einen dieser Verweise<br />

Max.<br />

Linie<br />

<strong>Die</strong> einheitliche Schnittstelle<br />

This is the Title of the Book, eMatter Edition<br />

| 117<br />

Copyright © 2007 O’Reilly & Associates, Inc. All rights reserved.<br />

<strong>Die</strong>s ist ein Auszug aus dem Buch „Web Services mit REST“, ISBN 978-3-89721-727-0<br />

http://www.oreilly.de/catalog/restfulwsger/<br />

<strong>Die</strong>ser Auszug unterliegt dem Urheberrecht. © <strong>O'Reilly</strong> <strong>Verlag</strong> 2008


Max.<br />

Linie<br />

klickte, wurde die entsprechende Seite schneller geladen, da der Computer sie schon<br />

empfangen hatte.<br />

Der Web Accelerator war ein Desaster. Nicht aufgrund eines Problems in der Software<br />

selbst, sondern weil das Web voll von Anwendungen ist, die GET missbrauchen.<br />

Der Web Accelerator nahm an, dass GET-Operationen sicher wären und<br />

Clients sie schon im Voraus laden konnten, falls jemand die entsprechende<br />

Repräsentation sehen wollte. Aber wenn diese GET-Anfragen an reale URIs<br />

geschickt wurden, änderten sich Datensätze. <strong>Die</strong> Leute verloren Daten.<br />

Man kann die Schuld hier großzügig verteilen: Programmierer sollten keine<br />

unsicheren Aktionen per GET ansprechbar machen, und Google hätte kein Tool für<br />

die reale Welt veröffentlichen sollen, das im realen WWW nicht funktioniert. <strong>Die</strong><br />

aktuelle Version des Web Accelerator ignoriert alle URIs, die Query-Variablen<br />

enthalten. Das löst einen Teil des Problems, verhindert aber auch, dass viele Ressourcen,<br />

die man per GET sicher laden könnte (wie zum Beispiel die Web-Suchen von<br />

Google), im Voraus geladen werden.<br />

Sie können noch viele Beispiele bekommen. Viele Web Services und Web-Anwendungen<br />

verwenden URIs als Eingabeparameter, und als Erstes schicken sie einen<br />

GET-Request, um eine Repräsentation einer Ressource zu erhalten. <strong>Die</strong>se Services<br />

wollen keine katastrophalen Nebeneffekte auslösen, aber sie haben es nicht in der<br />

Hand. Es ist Aufgabe des Service, einen GET-Request so zu handhaben, dass er mit<br />

dem HTTP-Standard konform ist.<br />

Warum die einheitliche Schnittstelle wichtig ist<br />

Wichtig an REST ist nicht, dass Sie die spezielle einheitliche Schnittstelle verwenden,<br />

die HTTP definiert. REST spezifiziert eine einheitliche Schnittstelle, sagt aber nicht,<br />

welche einheitliche Schnittstelle. GET, PUT und der Rest sind nicht für alle Zeiten<br />

die perfekte Schnittstelle. Wichtig ist die Einheitlichkeit: Jeder Service verwendet die<br />

HTTP-Schnittstelle auf die gleiche Art und Weise.<br />

Der Punkt ist nicht, dass GET der beste Name für eine lesende Operation ist,<br />

sondern dass GET im ganzen Web »Lesen« bedeutet – egal, welche Ressource Sie<br />

dabei ansprechen. Bei einem gegebenen URI einer Ressource ist es keine Frage, wie<br />

Sie eine Repräsentation erhalten: Sie schicken einen HTTP-GET-Request an diesen<br />

URI. <strong>Die</strong> einheitliche Schnittstelle lässt zwei Services sich so ähnlich werden wie zwei<br />

Web-Sites. Ohne diese Einheitlichkeit müssen Sie lernen, wie jeder Service Informationen<br />

erwartet und verschickt. <strong>Die</strong> Regeln könnten sich sogar von Ressource zu<br />

Ressource innerhalb eines Service unterscheiden.<br />

Sie können einem Computer beibringen zu verstehen, was GET bedeutet – dann gilt<br />

dieses Verständnis für jeden REST-konformen Web Service. Da gibt es auch nicht<br />

viel zu verstehen. Der für den Service spezifische Code kann sich dann um die Behand-<br />

Links<br />

Max.<br />

Linie<br />

118 | Kapitel 4: <strong>Die</strong> <strong>ressourcenorientierte</strong> <strong>Architektur</strong><br />

This is the Title of the Book, eMatter Edition<br />

Copyright © 2007 O’Reilly & Associates, Inc. All rights reserved.<br />

<strong>Die</strong>s ist ein Auszug aus dem Buch „Web Services mit REST“, ISBN 978-3-89721-727-0<br />

http://www.oreilly.de/catalog/restfulwsger/<br />

<strong>Die</strong>ser Auszug unterliegt dem Urheberrecht. © <strong>O'Reilly</strong> <strong>Verlag</strong> 2008


Rechts<br />

Max.<br />

Linie<br />

lung der Repräsentation kümmern. Ohne die einheitliche Schnittstelle erhalten Sie<br />

eine viel größere Anzahl an Methoden, die den Platz von GET einnehmen: doSearch<br />

und getPage und nextPrime. Jeder Service spricht eine andere Sprache. Das ist auch<br />

der Grund, warum ich überladenes POST nicht so sehr mag: Es verwandelt das einfache<br />

Esperanto der einheitlichen Schnittstelle in ein babylonisches Gewirr einmalig<br />

genutzter Untersprachen.<br />

Manche Anwendungen erweitern die einheitliche Schnittstelle von HTTP. Der offensichtlichste<br />

Fall ist da WebDAV, das acht neue HTTP-Methoden hinzufügt, unter<br />

anderem MOVE, COPY und SEARCH. <strong>Die</strong> Verwendung dieser Methoden in einem<br />

Web Service würde keine Regel von REST verletzen, da REST nicht aussagt, wie die<br />

einheitliche Schnittstelle aussehen soll. <strong>Die</strong> Nutzung dieser Methoden würde allerdings<br />

nicht in meine <strong>ressourcenorientierte</strong> <strong>Architektur</strong> passen (da ich die ROA<br />

explizit mit den Standard-HTTP-Methoden verbunden habe), wobei so ein Service<br />

trotzdem noch allgemein gesprochen ressourcenorientiert sein könnte.<br />

Der eigentliche Grund, warum man keine WebDAV-Methoden nutzen sollte, ist,<br />

dass Sie damit Ihren Service inkompatibel zu anderen REST-konformen Services<br />

machen. Ihr Service würde eine andere einheitliche Schnittstelle verwenden als die<br />

meisten anderen. Es gibt Web Services wie Subversion, die die WebDAV-Methoden<br />

nutzen, daher wäre Ihr Service nicht allein. Aber er wäre nur ein Teil eines weitaus<br />

kleineren Webs. Das ist der Grund dafür, dass das Entwickeln eigener HTTP-Methoden<br />

eine sehr, sehr schlechte Idee ist: Ihr eigenes Vokabular lässt die Community<br />

deutlich schrumpfen. Da können Sie auch gleich XML-RPC nutzen.<br />

Eine andere einheitliche Schnittstelle besteht einzig und allein aus HTTP GET und<br />

überladenem POST. Um eine Repräsentation einer Ressource zu erhalten, schicken<br />

Sie ein GET an ihren URI. Um eine Ressource zu erstellen, zu verändern oder zu<br />

löschen, schicken Sie ein POST. <strong>Die</strong>se Schnittstelle ist vollständig REST-konform,<br />

aber passt auch nicht zu meiner <strong>ressourcenorientierte</strong>n <strong>Architektur</strong>. <strong>Die</strong>se Schnittstelle<br />

ist gerade ausreichend, um zwischen sicheren und unsicheren Operationen zu<br />

unterscheiden. Eine <strong>ressourcenorientierte</strong> Web-Anwendung würde diese Schnittstelle<br />

nutzen, weil heutige HTML-Formulare nur GET und POST unterstützen.<br />

Das war’s!<br />

Das ist die <strong>ressourcenorientierte</strong> <strong>Architektur</strong>. Es gibt nur vier Konzepte:<br />

1. Ressourcen<br />

2. ihre Namen (URIs)<br />

3. ihre Repräsentationen<br />

4. die Verweise zwischen ihnen<br />

Max.<br />

Linie<br />

Das war’s! | 119<br />

This is the Title of the Book, eMatter Edition<br />

Copyright © 2007 O’Reilly & Associates, Inc. All rights reserved.<br />

<strong>Die</strong>s ist ein Auszug aus dem Buch „Web Services mit REST“, ISBN 978-3-89721-727-0<br />

http://www.oreilly.de/catalog/restfulwsger/<br />

<strong>Die</strong>ser Auszug unterliegt dem Urheberrecht. © <strong>O'Reilly</strong> <strong>Verlag</strong> 2008


Und es gibt vier Eigenschaften:<br />

1. Adressierbarkeit<br />

2. Zustandslosigkeit<br />

3. Verbindungshaftigkeit<br />

4. eine einheitliche Schnittstelle<br />

Natürlich bleibt eine Reihe Fragen offen. Wie sollten reale Daten in Ressourcen aufgeteilt<br />

und wie sollten diese Ressourcen organisiert werden? Was sollte dann in den<br />

HTTP-Requests und -Responses stehen? Ich werde einen Großteil der verbleibenden<br />

Seiten dazu nutzen, solche Fragen anzusprechen.<br />

Links<br />

Max.<br />

Linie<br />

Max.<br />

Linie<br />

120 | Kapitel 4: <strong>Die</strong> <strong>ressourcenorientierte</strong> <strong>Architektur</strong><br />

This is the Title of the Book, eMatter Edition<br />

Copyright © 2007 O’Reilly & Associates, Inc. All rights reserved.<br />

<strong>Die</strong>s ist ein Auszug aus dem Buch „Web Services mit REST“, ISBN 978-3-89721-727-0<br />

http://www.oreilly.de/catalog/restfulwsger/<br />

<strong>Die</strong>ser Auszug unterliegt dem Urheberrecht. © <strong>O'Reilly</strong> <strong>Verlag</strong> 2008

Hurra! Ihre Datei wurde hochgeladen und ist bereit für die Veröffentlichung.

Erfolgreich gespeichert!

Leider ist etwas schief gelaufen!