SlideShare uma empresa Scribd logo
1 de 4
Web Services leicht gemacht
REST-basierte Schnittstellen mit dem Symfony-Framework implementieren

Im Web 2.0 verfügen praktisch alle großen Anbieter über eine API. Application Programming Interfaces
ermöglichen anderen Applikationen den kontrollierten Zugang zu den eigenen Daten und bilden so die
Grundlage für Mash-Ups oder Third-Party-Applikationen. Das PHP-basierte MVC-Framework Symfony
macht es einfach, derartige Schnittstellen effizient und sauber zu entwickeln. Dieser Artikel beleuchtet
den Aufbau von solchen Application Programming Interfaces und demonstriert, wie sie sich mit Hilfe des
Symfony-Frameworks implementieren lassen. ↘ Daniel Haller

REST-basierte APIs spielen in den letzten Jahren eine immer wich-
tigere Rolle im Web 2.0. Mit Hilfe einer derartigen Schnittstelle
können Anbieter von Webdiensten anderen Anwendungen Daten
in kontrolliertem Umfang bereit stellen und sich auf diese Weise
Zielgruppen jenseits der eigenen Website erschließen. APIs sind so
zu einem sehr wichtigen Erfolgsfaktor geworden – man denke nur
an Twitter oder Facebook und deren Ökosystem von Third-Party-
Applikationen.
    Mit Hilfe des Symfony-Frameworks [1] lassen sich derartige APIs
auf Basis von REST [2] sehr effektiv umsetzen. Dies lässt sich am
besten anhand eines beispielhaften Anwendungsfalls verdeutli-
chen: Ein fiktiver Buchhändler stellt eine Schnittstelle bereit, über
den sich Informationen zum Angebot abfragen lassen und mit der
Verleger mit Hilfe eines dedizierten Clients neue Bücher direkt in
der Datenbank des Händlers speichern können.                                Symfony ist modular aufgebaut, einzelne Komponenten lassen sich auch ei-
                                                                            genständig verwenden.

Die Grundlagen von REST
                                                                            Die API in Symfony
Eine REST-basierte Schnittstelle besteht aus Ressourcen, die durch          Die Bestandteile einer REST-API lassen sich gut in Symfony abbil-
URIs adressierbar sind und in verschiedenen Repräsentationen dar-           den: Module beziehungsweise deren Actioncontroller stellen die
gestellt werden können. Ressourcen sind Informationen, die eigen-           Ressourcen dar, die sich mit Hilfe des Symfony-Routings beliebig
ständig referenziert werden sollen, beispielsweise Texte, ein               adressieren lassen. Dank des MVC-Patterns kann für jede ge-
Benutzerprofil oder eine Suchergebnisseite. Deren Repräsentation            wünschte Repräsentation ein eigenes Template definiert werden.
erfolgt meistens im XML-Format, da dieses Format die gewünschte                 Das Auslesen des Bücherbestands ist der wohl einfachste An-
Interoperabilität zwischen verschiedenen Systemen oder Plattfor-            wendungsfall: Der Request an einen URI liefert eine Liste mit Bü-
men noch am besten sicherstellen kann. Andere Formate wie JSON              chern. Im Grunde unterscheidet sich dieser Anwendungsfall vom
sind aber ebenfalls denkbar. Ressourcen lassen sich, wie auch im            herkömmlichen Abruf im Browser nur durch die Repräsentationen
Web, miteinander verlinken.                                                 der Response, die im XML- anstatt im HTML-Format dargestellt wird.
    Der Zugriff auf die API erfolgt ganz einfach durch das HTTP-                Dem Routing-System von Symfony kommt bei der Umsetzung
Protokoll. Die verschiedenen Methoden des Protokolls codieren die           einer REST-API eine wichtige Rolle zu. Durch die Routing-Regeln
Operationen auf der Anwendungsebene. Wird beispielsweise per                wird in erster Linie festgelegt, welchen URI eine Ressource be-
GET auf eine Ressource zugegriffen, weiß der Server, dass ein Lese-         kommt, mit welcher HTTP-Methode darauf zugegriffen werden darf
vorgang durchgeführt werden soll – derselbe Request mit der                 und welcher Actioncontroller den Request verarbeitet.
DELETE-Methode würde die Ressource hingegen löschen (mehr
dazu unter [3] ).                                                             Eine einfache Routing-Regel
                                                                             booklist: # Darstellung einer Liste mit dem Buchbestand
                                                                               url: /booklist.:sf_format
    Tools zum Testen von REST-APIs                                             class: sfRequestRoute
    REST-basierte Schnittstellen lassen sich nicht direkt im Browser ent-      param: { module: book, action: list, , sf_format: html }
    wickeln oder testen, da sich die HTTP-Methoden für den Request nicht       requirements: { sf_method: GET, sf_format: (?:xml|json|html) }
    festlegen lassen und auch kein direkter Zugriff auf weitere Parameter
                                                                            Listing 1
    des HTTP-Requests besteht. Abhilfe schafft das Programm
    „RESTClient“ (http://bit.ly/RESTClient) oder die Firefox-Erweiterung
    „RestTest“ (http://bit.ly/RESTTest).                                    Im Zusammenhang mit REST-APIs spielt insbesondere der sf_for-
                                                                            mat-Parameter eine wichtige Rolle. Durch ihn wird das Format

1   © yeebase media 2009. Veröffentlichung und Vervielfältigung nur mit Genehmigung der yeebase media GbR. http://t3n.yeebase.com
bestimmt, in dem die Ressource an den Client ausgeliefert wird. Der             bere Trennnung zu den Front- und Backend-Applikationen zu ha-
Standardwert ist HTML, erlaubt sind in diesem Beispiel aber auch                ben, die in fast jedem Symfony-Projekt vorhanden sind.
XML oder JSON. Alternativ lässt sich das Request-Format auch direkt                Eine neue API-Applikation samt Book-Modul ist dank der Kom-
in der Action festlegen (Listing 2), allerdings ist es eleganter, das           mandozeilentools schnell angelegt:
direkt über den URI zu tun.
                                                                                  API-Applikation genieren
  Request-Format im Controller setzen                                            $ symfony generate:app api
                                                                                 $ symfony generate:module api book
 $request->setRequestFormat('xml');
                                                                                Listing 3
Listing 2

                                                                                Für das Book-Modul das Scaffolding zu verwenden, ist durchaus
Durch den sf_method-Parameter wird festgelegt, mit welchen Me-
                                                                                möglich, aber nicht unbedingt sinnvoll: Es werden dann zwar alle
thoden eine Ressource aufgerufen werden kann. Dies kann beson-
                                                                                nötigen Methoden im Actioncontroller angelegt, diese gehen aber
ders bei komplexeren APIs praktisch sein – zum Beispiel lässt sich
                                                                                davon aus, dass die Daten zum Anlegen oder Ändern von Daten-
so der Request für eine Ressource per DELETE-Methode unterbin-
                                                                                sätzen von den ebenfalls generierten (HTML-)Formularen in den
den.
                                                                                Templates stammen. Für die API allerdings müssen diese stattdes-
    Für komplexere Requests mit mehr Parametern ist es darüber
                                                                                sen aus den HTTP-Bodys extrahiert werden, wo sie im XML-Format
hinaus sogar möglich, bereits im Routing eine Validierung der GET-
                                                                                an die Schnittstelle übertragen werden.
Parameter per regulärem Ausdruck vorzunehmen.
                                                                                    Bei einer dedizierten Applikation für die API kann auch die View-
                                                                                Konfiguration geändert werden (Listing 4): Ein Layout wird jetzt
                                                                                nicht mehr benötigt, da die Templates aus reinem XML bestehen.
                                                                                Außerdem wird auch der standardmäßige Content-Type ange-
                                                                                passt.

                                                                                  Anpassungen an der view.yml für die API
                                                                                 default:
                                                                                   http_metas:
                                                                                     content-type: text/xml
                                                                                   has_layout: off

                                                                                Listing 4

                                                                                Symfony und das Doctrine-ORM stellen für das Routing einen nütz-
                                                                                lichen Shortcut bereit:
Der Aufbau von Symfony gliedert sich in eine Plattform und das darauf aufset-
zende Framework.                                                                  Shortcut in der routing.yml
                                                                                 book:
Die Bücherliste kann außer im HTML-Format auch als XML- oder                       class: sfDoctrineRouteCollection
                                                                                   options: { model: Book }
JSON-Repräsentation angefordert werden. Dazu müssen für jedes
Format eigene Templates angelegt werden und Symfony wählt auf                   Listing 5
Basis des gesetzten sf_request-Parameters das Passende aus. Aus-
schlaggebend ist hierbei die Dateiendung: listSuccess.php für eine              Diese Regel wird zu einer Reihe REST-konformer Routen aufgelöst,
standardmäßige HTML-Repräsentation, listSuccess.xml.php für                     ähnlich wie jener in Listing 1, die man sich in der Zusammenfassung
XML und listSuccess.json.php für JSON.                                          auch durch die Kommandozeile anzeigen lassen kann:
    Symfony liefert standardmäßig nur die HTML-Repräsentation
mit einem Layout aus, das bei JSON oder XML natürlich entfällt.                   Routen in der API
Außerdem kümmert sich das Framework selbstständig um den kor-                    $ symfony app:routes
rekten Content-Type (text/xml bzw. text/x-json) im HTTP-Header.                  >> app    Current routes for application
                                                                                 Name      Method       Pattern
                                                                                 book          GET     /book.:sf_format
Komplexer: Datenmanipulation                                                     book_new      GET
                                                                                 book_create POST
                                                                                                       /book/new.:sf_format
                                                                                                        /book.:sf_format
                                                                                 book_edit     GET     /book/:id/edit.:sf_for
Mit den beschriebenen Funktionen hat man im Prinzip bereits alles                book_update PUT /book/:id.:sf_format
zusammen, was man braucht, um eine sehr einfache API zum Aus-                    book_delete DELETE /book/:id.:sf_format
lesen und Bereitstellen von Daten zu implementieren. Anspruchs-                  book_show      GET     /book/:id.:sf_format

voller wird es jedoch, wenn die API nicht nur Daten auslesen,                   Listing 6
sondern auch ändern, löschen oder erstellen soll. Ein weitaus kom-
plexeres Anwendungsszenario ist daher die Implementierung einer                 Diese Routen verweisen auf die jeweiligen Methoden (new, create,
Schnittstellenfunktion, mit der ein Verleger neue Bücher direkt aus             edit, update usw.) im Actioncontroller des Book-Moduls, die später
dem eigenen Warenwirtschaftssystem in das Shop-System über-                     implementiert werden müssen.
tragen kann. Aus einer „lesenden“ wird so eine „schreibende“ API.                   Für den Einsatz innerhalb einer API sollten die „Edit“- und
    Je umfangreicher eine API wird, desto sinnvoller kann es sein,              „New“-Methoden nicht implementiert werden beziehungsweise
diese in eine eigenständige Applikation auszulagern um eine sau-                eine Fehlermeldung werfen, da eine GET-Methode niemals in der

© yeebase media 2009. Veröffentlichung und Vervielfältigung nur mit Genehmigung der yeebase media GbR. http://t3n.yeebase.com                      2
Lage sein sollte, Daten auf einem Server in irgendeiner Weise zu                            koppelt dabei ein Datenbankobjekt direkt mit dem ID-Parameter in
ändern (oder zu erstellen). Das ist ausschließlich den idempotenten                         der URL, sodass man im Controller darauf zugreifen und sich eigene
Methoden PUT, POST und DELETE vorbehalten.                                                  Queries weitgehend sparen kann. Wird kein Datensatz mit der ge-
                                                                                            wünschten ID gefunden, wirft Symfony einen 404-Fehler. Die Im-
Authentifizierung durch API-Keys                                                            plementierung der Controller-Methoden geht daher schnell von
                                                                                            der Hand. Um die Dateilansicht eines Buchs anzuzeigen, reicht eine
Natürlich sollen nur autorisierte Benutzer Datensätze erstellen oder
                                                                                            Zeile im Controller:
ändern dürfen. Bevor also eine Aktion ausgeführt wird, muss sich
der Benutzer zunächst gegenüber der API authentifizieren. Eine
                                                                                              Detailansicht eines Buchs
Möglichkeit dazu ist die Verwendung von API-Keys. Der API-Key
kann im HTTP-Header (zum Beispiel als „X-ApiKey“) mitgeschickt                               // HTTP-Request: GET /book/[id] HTTP/1.1
                                                                                             public function executeShow(sfWebRequest $request) {
werden und dient als Ersatz für die übliche Benutzernamen/Pass-
                                                                                                $this->book = $this->getRoute()->getObject(); // $this->book is now available
wort-Kombination (sinnvollerweise sollten Requests an die API in                             in the template
diesem Fall per HTTP/S gesichert werden). Die Authentifizierung                              }

kann in Symfony als Filter (Listing 7) implementiert werden, der vor                        Listing 9
dem Abarbeiten des eigentlichen Requests im Controller durch-
laufen wird und in der filter.yml aktiviert werden muss.                                    Ein Request für denselben URI mit der DELETE-Methode wird REST-
                                                                                            konform zur Delete-Methode geroutet:
    API-Filter Klasse
    class apiFilter extends sfFilter {                                                        Ein Buch löschen
       public function execute($filterChain) {
         if ($this->isFirstCall()) {                                                         // HTTP-Request: DELETE /book/[id] HTTP/1.1
           $request = $this->getContext()->getRequest();                                     public function executeDelete(sfWebRequest $request) {
              $session = $this->getContext()->getUser();                                       $book = $this->getRoute()->getObject();
             // Get API-Key from HTTP-Header                                                   // User allowed to delete this Book? If not, stop execution and send HTTP-
             $apikey = $request->getHttpHeader('X-ApiKey');                                  Statuscode 403
             // Select user from database by given API-Key                                     $this->checkPermission($book);
             $userprofile = Doctrine::getTable('User')->findOneByApikey($apikey);              // ...User has Permission, let's delete this Book
             // Throw an error if user cannot be found...                                      $book->delete();
             jeHTTPError::forwardUnless($userprofile, 401, 'Invalid or missing API-Key');    }
             // ...or save the user in the session
             $session->setAttribute('user',$userprofile);                                   Listing 10
         }
         // Execute next filter in filter symfonys filter chain
         $filterChain->execute();
                                                                                            Mit den POST- und PUT-Methoden wird ein neues Buch angelegt
         // Code to execute AFTER the action execution, before the rendering                beziehungsweise ein bestehendes Buch geändert. Die dazu erfor-
         // Delete User-Session after every API-Request                                     derlichen Daten werden als XML im HTTP-Body übertragen und
         session_unset();
         session_destroy();                                                                 müssen daher ausgelesen und geparst werden. Hierzu kann man
       }                                                                                    im lib-Verzeichnis in einer Klasse eine einfache Methode (Listing 11)
    }
                                                                                            implementieren, die bei Gebrauch durch den Autoload-Mechanis-
Listing 7                                                                                   mus von Symfony inkludiert wird.

Dieser Filter lädt zum einen das Benutzerobjekt anhand des API-                               Auslesen der XML-Nutzlast
Keys im Header aus der Datenbank und speichert es in der Symfony-
                                                                                             class Tools {
Benutzersession, sodass es überall im Code zur Verfügung steht. Ist                             public static function getRequestBody () {
der API-Key nicht korrekt, wird stattdessen eine Fehlermeldung mit                                $stream = fopen("php://input", "r");
                                                                                                  $data = stream_get_contents($stream);
entsprechendem HTTP-Statuscode gesendet. Zum anderen muss                                         fclose($stream);
die Session wieder gelöscht werden, nachdem der Request abge-                                     return simplexml_load_string($data);
arbeitet wurde. REST ist per Definition zustandslos, das heisst eine                            }
                                                                                             }
„klassische“ Session wird nicht gespeichert.
    Für das Error-Handling kann wie in Listing 7 das jeHTTPError-                           Listing 11
Exception-Plugin genutzt werden, welches das Symfony-Error
Handling um die Fähigkeit erweitert, beliebige HTTP-Statuscodes                             Ein neues Buch lässt sich ebenfalls sehr einfach erzeugen:
und Fehlermeldungen in der Response zurückzugeben. Gerade im
Zusammenhang mit REST ist das eine praktische Sache. Das Plugin                               Ein neues Buch anlegen
lässt sich mit Hilfe des CLI schnell installieren:                                           // HTTP-Request: POST /book HTTP/1.1
                                                                                             public function executeCreate(sfWebRequest $request) {
    Plugin installieren                                                                        $data = Tools::getRequestBody();
                                                                                               $book = new Book();
                                                                                               $book->saveBook($data); // Save Book in the Model
    $ symfony plugin:install jeHTTPErrorExceptionPlugin
                                                                                               $this->getResponse()->setStatusCode(201);
                                                                                               $this->getResponse()->setHttpHeader('Location',
Listing 8
                                                                                                 $request->getHost().'/book/'.$book->get('id'));
                                                                                             }
Der Controller des Book-Moduls                                                              Listing 12
In Listing 5 werden Routen auf die Index-, Show-, Create-, Update-,
und Delete-Methoden des Book-Controllers erzeugt, die imple-                                In dieser Methode werden die Daten zunächst aus dem Request-
mentiert werden müssen. Die sfDoctrineRouteCollection-Klasse                                Body extrahiert und an das Model übergeben, wo das neue Buch

3     © yeebase media 2009. Veröffentlichung und Vervielfältigung nur mit Genehmigung der yeebase media GbR. http://t3n.yeebase.com
dann angelegt wird. Wichtig ist, dem Client im Response per HTTP-
Statuscode mitzuteilen, dass die Ressource erzeugt wurde („201 –
Created“) und deren (neue) URI im Location-Header anzugeben.
    Analog dazu funktioniert das Editieren eines Buchs:

  Ein bestehendes Buch editieren
 // HTTP-Request: PUT /book/[id] HTTP/1.1
 public function executeUpdate(sfWebRequest $request) {
   $data = Tools::getRequestBody();
   $book = $this->getRoute()->getObject();
   // User allowed to edit Book? If not, stop execution, send HTTP-Statuscode 403
   $this->checkPermission($book);
   $book->saveBook($data);
 }

Listing 13


Für alle genannten Methoden müssen natürlich auch die jeweiligen
(XML-)Templates angelegt werden, um einem Client das ge-
wünschte Feedback – zum Beispiel in Form einer Statusmeldung –
geben zu können. Für die Validierung der Benutzerdaten bringt
Symfony eine Reihe von Standard-Validatoren mit, die allerdings
primär zur Verwendung mit dem Formular-Framework gedacht
sind. Noch einfacher lassen sich alternativ die Validatoren des Doc-
trine-ORMs [4] verwenden, die man bereits in der Schema-Datei
konfigurieren kann und die die Daten noch auf der Anwendungs-
ebene unmittelbar vor dem Speichern in der Datenbank validieren.


Zusammenfassung
Mit Hilfe des Symfony-Frameworks lassen sich REST-basierte
Schnittstellen sehr sauber und vergleichsweise einfach implemen-
tieren. Dieser Artikel zeigt nur einen von vielen Ansätzen, der sich
aber grundsätzlich auch für umfangreiche APIs eignet – selbst wenn
für den produktiven Einsatz noch einige Aspekte tiefer ausgearbei-
tet werden müssten. ↔



Links und Literatur                ↗ Softlink 2426
[1]   Offizielle Website des Symfony-Projekts: http://www.symfony-
      project.org/
[2]   Wikipedia-Eintrag zu REST: http://de.wikipedia.org/wiki/
      Representational_State_Transfer
[3]   OIO: REST Web Services: http://www.oio.de/public/xml/rest-
      webservices.pdf
[4]   Doctrine Data Validation: http://www.doctrine-project.org/
      documentation/manual/1_1/en/data-validation



  Der Autor

                              Daniel Haller ist bei der Frankfurter Agen-
                              tur BlueMars als Technischer Projektma-
                              nager und Web Developer tätig. Mit REST-
                              basierten APIs hat er sich im Rahmen seiner
                              Diplomarbeit zum Media System Designer
                              in Darmstadt beschäftigt. Er ist begeister-
                              ter Anwender des Symfony-Frameworks.




© yeebase media 2009. Veröffentlichung und Vervielfältigung nur mit Genehmigung der yeebase media GbR. http://t3n.yeebase.com 4

Mais conteúdo relacionado

Destaque

IID-Designprojekt Präsentation
IID-Designprojekt PräsentationIID-Designprojekt Präsentation
IID-Designprojekt PräsentationGexTM
 
Web 2.0-Zauberschule - praktische Anwendung für die praktische Unterrichtsvor...
Web 2.0-Zauberschule - praktische Anwendung für die praktische Unterrichtsvor...Web 2.0-Zauberschule - praktische Anwendung für die praktische Unterrichtsvor...
Web 2.0-Zauberschule - praktische Anwendung für die praktische Unterrichtsvor...Monika Wisła
 
Antifaschismus in Deutschland
Antifaschismus in DeutschlandAntifaschismus in Deutschland
Antifaschismus in DeutschlandPatrick Balk
 
Social Media für Freiberufler und Künstler
Social Media für Freiberufler und KünstlerSocial Media für Freiberufler und Künstler
Social Media für Freiberufler und KünstlerFrank Koebsch
 
Seminarverwaltung Uni Hohenheim
Seminarverwaltung Uni HohenheimSeminarverwaltung Uni Hohenheim
Seminarverwaltung Uni HohenheimDaniel Fehrle
 
Pflegerentenversicherung: Die finanzielle Absicherung für den Pflegefall im B...
Pflegerentenversicherung: Die finanzielle Absicherung für den Pflegefall im B...Pflegerentenversicherung: Die finanzielle Absicherung für den Pflegefall im B...
Pflegerentenversicherung: Die finanzielle Absicherung für den Pflegefall im B...Ellwanger & Geiger Privatbankiers
 
GEVIS als Baustein zur Umsetzung der GEVER Verordnung - Architekturboard UVEK...
GEVIS als Baustein zur Umsetzung der GEVER Verordnung - Architekturboard UVEK...GEVIS als Baustein zur Umsetzung der GEVER Verordnung - Architekturboard UVEK...
GEVIS als Baustein zur Umsetzung der GEVER Verordnung - Architekturboard UVEK...Hans Ulrich Wiedmer
 
Social Media & Rekrutierung: Hype oder Standard?
Social Media & Rekrutierung: Hype oder Standard?Social Media & Rekrutierung: Hype oder Standard?
Social Media & Rekrutierung: Hype oder Standard?Yves Maeder
 
Definiciones
DefinicionesDefiniciones
DefinicionesAnylara
 
Animals in danger
Animals in dangerAnimals in danger
Animals in dangeriesMola
 
Visteonwireframes
VisteonwireframesVisteonwireframes
VisteonwireframesSuzie Are
 
Bankettdokumentation Hotel Walzenhausen
Bankettdokumentation Hotel WalzenhausenBankettdokumentation Hotel Walzenhausen
Bankettdokumentation Hotel Walzenhausensdh_walzenhausen
 
E&G: Trend zur Nachhaltigkeit als Investitionschance nutzen
E&G: Trend zur Nachhaltigkeit als Investitionschance nutzen E&G: Trend zur Nachhaltigkeit als Investitionschance nutzen
E&G: Trend zur Nachhaltigkeit als Investitionschance nutzen Ellwanger & Geiger Privatbankiers
 
DIE MARKTMEINUNG AUS STUTTGART - Konjunktursorgen belasten die Aktienmärkte
DIE MARKTMEINUNG AUS STUTTGART - Konjunktursorgen belasten die AktienmärkteDIE MARKTMEINUNG AUS STUTTGART - Konjunktursorgen belasten die Aktienmärkte
DIE MARKTMEINUNG AUS STUTTGART - Konjunktursorgen belasten die AktienmärkteEllwanger & Geiger Privatbankiers
 

Destaque (18)

IID-Designprojekt Präsentation
IID-Designprojekt PräsentationIID-Designprojekt Präsentation
IID-Designprojekt Präsentation
 
Web 2.0-Zauberschule - praktische Anwendung für die praktische Unterrichtsvor...
Web 2.0-Zauberschule - praktische Anwendung für die praktische Unterrichtsvor...Web 2.0-Zauberschule - praktische Anwendung für die praktische Unterrichtsvor...
Web 2.0-Zauberschule - praktische Anwendung für die praktische Unterrichtsvor...
 
Antifaschismus in Deutschland
Antifaschismus in DeutschlandAntifaschismus in Deutschland
Antifaschismus in Deutschland
 
Social Media für Freiberufler und Künstler
Social Media für Freiberufler und KünstlerSocial Media für Freiberufler und Künstler
Social Media für Freiberufler und Künstler
 
Was tun wir in Frankfurt?
Was tun wir in Frankfurt?Was tun wir in Frankfurt?
Was tun wir in Frankfurt?
 
Seminarverwaltung Uni Hohenheim
Seminarverwaltung Uni HohenheimSeminarverwaltung Uni Hohenheim
Seminarverwaltung Uni Hohenheim
 
Pflegerentenversicherung: Die finanzielle Absicherung für den Pflegefall im B...
Pflegerentenversicherung: Die finanzielle Absicherung für den Pflegefall im B...Pflegerentenversicherung: Die finanzielle Absicherung für den Pflegefall im B...
Pflegerentenversicherung: Die finanzielle Absicherung für den Pflegefall im B...
 
Neue digitale Arbeitswelten - Kreativökonomie im Wandel
Neue digitale Arbeitswelten - Kreativökonomie im WandelNeue digitale Arbeitswelten - Kreativökonomie im Wandel
Neue digitale Arbeitswelten - Kreativökonomie im Wandel
 
GEVIS als Baustein zur Umsetzung der GEVER Verordnung - Architekturboard UVEK...
GEVIS als Baustein zur Umsetzung der GEVER Verordnung - Architekturboard UVEK...GEVIS als Baustein zur Umsetzung der GEVER Verordnung - Architekturboard UVEK...
GEVIS als Baustein zur Umsetzung der GEVER Verordnung - Architekturboard UVEK...
 
Corr cont
Corr contCorr cont
Corr cont
 
Social Media & Rekrutierung: Hype oder Standard?
Social Media & Rekrutierung: Hype oder Standard?Social Media & Rekrutierung: Hype oder Standard?
Social Media & Rekrutierung: Hype oder Standard?
 
Definiciones
DefinicionesDefiniciones
Definiciones
 
Animals in danger
Animals in dangerAnimals in danger
Animals in danger
 
Visteonwireframes
VisteonwireframesVisteonwireframes
Visteonwireframes
 
Crowdsourcing Summit: Ideenreichtum & Innovationen aus der Crowd
Crowdsourcing Summit: Ideenreichtum & Innovationen aus der CrowdCrowdsourcing Summit: Ideenreichtum & Innovationen aus der Crowd
Crowdsourcing Summit: Ideenreichtum & Innovationen aus der Crowd
 
Bankettdokumentation Hotel Walzenhausen
Bankettdokumentation Hotel WalzenhausenBankettdokumentation Hotel Walzenhausen
Bankettdokumentation Hotel Walzenhausen
 
E&G: Trend zur Nachhaltigkeit als Investitionschance nutzen
E&G: Trend zur Nachhaltigkeit als Investitionschance nutzen E&G: Trend zur Nachhaltigkeit als Investitionschance nutzen
E&G: Trend zur Nachhaltigkeit als Investitionschance nutzen
 
DIE MARKTMEINUNG AUS STUTTGART - Konjunktursorgen belasten die Aktienmärkte
DIE MARKTMEINUNG AUS STUTTGART - Konjunktursorgen belasten die AktienmärkteDIE MARKTMEINUNG AUS STUTTGART - Konjunktursorgen belasten die Aktienmärkte
DIE MARKTMEINUNG AUS STUTTGART - Konjunktursorgen belasten die Aktienmärkte
 

Semelhante a Web Services leicht gemacht

Metaprogrammierung und Reflection
Metaprogrammierung und ReflectionMetaprogrammierung und Reflection
Metaprogrammierung und ReflectionStefan Marr
 
Ecm 5 13_djaafar_jas_forge
Ecm 5 13_djaafar_jas_forgeEcm 5 13_djaafar_jas_forge
Ecm 5 13_djaafar_jas_forgeJasmine Conseil
 
Biexcellence technische konzepte_2014_de
Biexcellence technische konzepte_2014_deBiexcellence technische konzepte_2014_de
Biexcellence technische konzepte_2014_debi_user
 
Lotus Notes SAP Integration Wünsch AG
Lotus Notes SAP Integration Wünsch AGLotus Notes SAP Integration Wünsch AG
Lotus Notes SAP Integration Wünsch AGWünsch AG
 
6 - Sprachen des Semantic Web - RDF(S) Frameworks
6 - Sprachen des Semantic Web - RDF(S) Frameworks6 - Sprachen des Semantic Web - RDF(S) Frameworks
6 - Sprachen des Semantic Web - RDF(S) FrameworksSteffen Schloenvoigt
 
OpenBib und Linked Open Data - Weiterentwicklung eines Recherche-Portals
OpenBib und Linked Open Data - Weiterentwicklung eines Recherche-PortalsOpenBib und Linked Open Data - Weiterentwicklung eines Recherche-Portals
OpenBib und Linked Open Data - Weiterentwicklung eines Recherche-Portalsflimm
 
06 Software Development Guidelines der COMLINE Cloud Service Platform - CSP
06 Software Development Guidelines der COMLINE Cloud Service Platform - CSP06 Software Development Guidelines der COMLINE Cloud Service Platform - CSP
06 Software Development Guidelines der COMLINE Cloud Service Platform - CSPChristian Guenther
 
Schnittstellen und Webservices
Schnittstellen und WebservicesSchnittstellen und Webservices
Schnittstellen und WebservicesJakob .
 
Morphia, Spring Data & Co
Morphia, Spring Data & CoMorphia, Spring Data & Co
Morphia, Spring Data & CoTobias Trelle
 
SCD13: Verwendung und Erweiterbarkeit der Rest-API
SCD13: Verwendung und Erweiterbarkeit der Rest-APISCD13: Verwendung und Erweiterbarkeit der Rest-API
SCD13: Verwendung und Erweiterbarkeit der Rest-APIshopware AG
 
Hypermedia mit der ASP.NET Web API
Hypermedia mit der ASP.NET Web APIHypermedia mit der ASP.NET Web API
Hypermedia mit der ASP.NET Web APIAlexander Zeitler
 
Web APIs auf dem Prüfstand - Volle Kontrolle oder fertig mit den Azure Mobile...
Web APIs auf dem Prüfstand - Volle Kontrolle oder fertig mit den Azure Mobile...Web APIs auf dem Prüfstand - Volle Kontrolle oder fertig mit den Azure Mobile...
Web APIs auf dem Prüfstand - Volle Kontrolle oder fertig mit den Azure Mobile...Peter Kirchner
 
B&IT Kurzpräsentation EPO AFS Suche - Die flexible SAP-Suchmaschine
B&IT Kurzpräsentation EPO AFS Suche - Die flexible SAP-SuchmaschineB&IT Kurzpräsentation EPO AFS Suche - Die flexible SAP-Suchmaschine
B&IT Kurzpräsentation EPO AFS Suche - Die flexible SAP-SuchmaschineWolfgang Hornung
 
Echtes Single Sign-On mit APEX realisieren
Echtes Single Sign-On mit APEX realisierenEchtes Single Sign-On mit APEX realisieren
Echtes Single Sign-On mit APEX realisierenMT AG
 
Freelance Cakephp Programmierer
Freelance Cakephp ProgrammiererFreelance Cakephp Programmierer
Freelance Cakephp Programmiererheliossolutionsde
 
API-Industrie
API-IndustrieAPI-Industrie
API-Industriekspichale
 
Einbindung von Linked Data in existierende Bibliotheksanswendungen
Einbindung von Linked Data in existierende BibliotheksanswendungenEinbindung von Linked Data in existierende Bibliotheksanswendungen
Einbindung von Linked Data in existierende Bibliotheksanswendungenredsys
 
Ruby On Rails Einführung
Ruby On Rails EinführungRuby On Rails Einführung
Ruby On Rails EinführungReinhold Weber
 

Semelhante a Web Services leicht gemacht (20)

Metaprogrammierung und Reflection
Metaprogrammierung und ReflectionMetaprogrammierung und Reflection
Metaprogrammierung und Reflection
 
Ecm 5 13_djaafar_jas_forge
Ecm 5 13_djaafar_jas_forgeEcm 5 13_djaafar_jas_forge
Ecm 5 13_djaafar_jas_forge
 
Biexcellence technische konzepte_2014_de
Biexcellence technische konzepte_2014_deBiexcellence technische konzepte_2014_de
Biexcellence technische konzepte_2014_de
 
Lotus Notes SAP Integration Wünsch AG
Lotus Notes SAP Integration Wünsch AGLotus Notes SAP Integration Wünsch AG
Lotus Notes SAP Integration Wünsch AG
 
6 - Sprachen des Semantic Web - RDF(S) Frameworks
6 - Sprachen des Semantic Web - RDF(S) Frameworks6 - Sprachen des Semantic Web - RDF(S) Frameworks
6 - Sprachen des Semantic Web - RDF(S) Frameworks
 
OpenBib und Linked Open Data - Weiterentwicklung eines Recherche-Portals
OpenBib und Linked Open Data - Weiterentwicklung eines Recherche-PortalsOpenBib und Linked Open Data - Weiterentwicklung eines Recherche-Portals
OpenBib und Linked Open Data - Weiterentwicklung eines Recherche-Portals
 
06 Software Development Guidelines der COMLINE Cloud Service Platform - CSP
06 Software Development Guidelines der COMLINE Cloud Service Platform - CSP06 Software Development Guidelines der COMLINE Cloud Service Platform - CSP
06 Software Development Guidelines der COMLINE Cloud Service Platform - CSP
 
Schnittstellen und Webservices
Schnittstellen und WebservicesSchnittstellen und Webservices
Schnittstellen und Webservices
 
Morphia, Spring Data & Co
Morphia, Spring Data & CoMorphia, Spring Data & Co
Morphia, Spring Data & Co
 
SCD13: Verwendung und Erweiterbarkeit der Rest-API
SCD13: Verwendung und Erweiterbarkeit der Rest-APISCD13: Verwendung und Erweiterbarkeit der Rest-API
SCD13: Verwendung und Erweiterbarkeit der Rest-API
 
Hypermedia mit der ASP.NET Web API
Hypermedia mit der ASP.NET Web APIHypermedia mit der ASP.NET Web API
Hypermedia mit der ASP.NET Web API
 
Web APIs auf dem Prüfstand - Volle Kontrolle oder fertig mit den Azure Mobile...
Web APIs auf dem Prüfstand - Volle Kontrolle oder fertig mit den Azure Mobile...Web APIs auf dem Prüfstand - Volle Kontrolle oder fertig mit den Azure Mobile...
Web APIs auf dem Prüfstand - Volle Kontrolle oder fertig mit den Azure Mobile...
 
Webtechnologien - Technische Anforderungen an Informationssysteme
Webtechnologien - Technische Anforderungen an InformationssystemeWebtechnologien - Technische Anforderungen an Informationssysteme
Webtechnologien - Technische Anforderungen an Informationssysteme
 
B&IT Kurzpräsentation EPO AFS Suche - Die flexible SAP-Suchmaschine
B&IT Kurzpräsentation EPO AFS Suche - Die flexible SAP-SuchmaschineB&IT Kurzpräsentation EPO AFS Suche - Die flexible SAP-Suchmaschine
B&IT Kurzpräsentation EPO AFS Suche - Die flexible SAP-Suchmaschine
 
Echtes Single Sign-On mit APEX realisieren
Echtes Single Sign-On mit APEX realisierenEchtes Single Sign-On mit APEX realisieren
Echtes Single Sign-On mit APEX realisieren
 
Freelance Cakephp Programmierer
Freelance Cakephp ProgrammiererFreelance Cakephp Programmierer
Freelance Cakephp Programmierer
 
CMS Kurs-Glossar
CMS Kurs-GlossarCMS Kurs-Glossar
CMS Kurs-Glossar
 
API-Industrie
API-IndustrieAPI-Industrie
API-Industrie
 
Einbindung von Linked Data in existierende Bibliotheksanswendungen
Einbindung von Linked Data in existierende BibliotheksanswendungenEinbindung von Linked Data in existierende Bibliotheksanswendungen
Einbindung von Linked Data in existierende Bibliotheksanswendungen
 
Ruby On Rails Einführung
Ruby On Rails EinführungRuby On Rails Einführung
Ruby On Rails Einführung
 

Mais de Daniel Haller

HTML5 für Einsteiger, Designer und Projektmanager
HTML5 für Einsteiger, Designer und ProjektmanagerHTML5 für Einsteiger, Designer und Projektmanager
HTML5 für Einsteiger, Designer und ProjektmanagerDaniel Haller
 
Kanban: Keep it simple
Kanban: Keep it simpleKanban: Keep it simple
Kanban: Keep it simpleDaniel Haller
 
Netbiscuits - 9 Tipps
Netbiscuits - 9 Tipps Netbiscuits - 9 Tipps
Netbiscuits - 9 Tipps Daniel Haller
 
Netzneutralität - Eine Einführung in das Thema
Netzneutralität - Eine Einführung in das ThemaNetzneutralität - Eine Einführung in das Thema
Netzneutralität - Eine Einführung in das ThemaDaniel Haller
 
Mobile Strategy / Apps, WebApps, HybridApps
Mobile Strategy / Apps, WebApps, HybridAppsMobile Strategy / Apps, WebApps, HybridApps
Mobile Strategy / Apps, WebApps, HybridAppsDaniel Haller
 

Mais de Daniel Haller (6)

HTML5 für Einsteiger, Designer und Projektmanager
HTML5 für Einsteiger, Designer und ProjektmanagerHTML5 für Einsteiger, Designer und Projektmanager
HTML5 für Einsteiger, Designer und Projektmanager
 
Kanban: Keep it simple
Kanban: Keep it simpleKanban: Keep it simple
Kanban: Keep it simple
 
Netbiscuits - 9 Tipps
Netbiscuits - 9 Tipps Netbiscuits - 9 Tipps
Netbiscuits - 9 Tipps
 
Kanban HowTo
Kanban HowToKanban HowTo
Kanban HowTo
 
Netzneutralität - Eine Einführung in das Thema
Netzneutralität - Eine Einführung in das ThemaNetzneutralität - Eine Einführung in das Thema
Netzneutralität - Eine Einführung in das Thema
 
Mobile Strategy / Apps, WebApps, HybridApps
Mobile Strategy / Apps, WebApps, HybridAppsMobile Strategy / Apps, WebApps, HybridApps
Mobile Strategy / Apps, WebApps, HybridApps
 

Web Services leicht gemacht

  • 1. Web Services leicht gemacht REST-basierte Schnittstellen mit dem Symfony-Framework implementieren Im Web 2.0 verfügen praktisch alle großen Anbieter über eine API. Application Programming Interfaces ermöglichen anderen Applikationen den kontrollierten Zugang zu den eigenen Daten und bilden so die Grundlage für Mash-Ups oder Third-Party-Applikationen. Das PHP-basierte MVC-Framework Symfony macht es einfach, derartige Schnittstellen effizient und sauber zu entwickeln. Dieser Artikel beleuchtet den Aufbau von solchen Application Programming Interfaces und demonstriert, wie sie sich mit Hilfe des Symfony-Frameworks implementieren lassen. ↘ Daniel Haller REST-basierte APIs spielen in den letzten Jahren eine immer wich- tigere Rolle im Web 2.0. Mit Hilfe einer derartigen Schnittstelle können Anbieter von Webdiensten anderen Anwendungen Daten in kontrolliertem Umfang bereit stellen und sich auf diese Weise Zielgruppen jenseits der eigenen Website erschließen. APIs sind so zu einem sehr wichtigen Erfolgsfaktor geworden – man denke nur an Twitter oder Facebook und deren Ökosystem von Third-Party- Applikationen. Mit Hilfe des Symfony-Frameworks [1] lassen sich derartige APIs auf Basis von REST [2] sehr effektiv umsetzen. Dies lässt sich am besten anhand eines beispielhaften Anwendungsfalls verdeutli- chen: Ein fiktiver Buchhändler stellt eine Schnittstelle bereit, über den sich Informationen zum Angebot abfragen lassen und mit der Verleger mit Hilfe eines dedizierten Clients neue Bücher direkt in der Datenbank des Händlers speichern können. Symfony ist modular aufgebaut, einzelne Komponenten lassen sich auch ei- genständig verwenden. Die Grundlagen von REST Die API in Symfony Eine REST-basierte Schnittstelle besteht aus Ressourcen, die durch Die Bestandteile einer REST-API lassen sich gut in Symfony abbil- URIs adressierbar sind und in verschiedenen Repräsentationen dar- den: Module beziehungsweise deren Actioncontroller stellen die gestellt werden können. Ressourcen sind Informationen, die eigen- Ressourcen dar, die sich mit Hilfe des Symfony-Routings beliebig ständig referenziert werden sollen, beispielsweise Texte, ein adressieren lassen. Dank des MVC-Patterns kann für jede ge- Benutzerprofil oder eine Suchergebnisseite. Deren Repräsentation wünschte Repräsentation ein eigenes Template definiert werden. erfolgt meistens im XML-Format, da dieses Format die gewünschte Das Auslesen des Bücherbestands ist der wohl einfachste An- Interoperabilität zwischen verschiedenen Systemen oder Plattfor- wendungsfall: Der Request an einen URI liefert eine Liste mit Bü- men noch am besten sicherstellen kann. Andere Formate wie JSON chern. Im Grunde unterscheidet sich dieser Anwendungsfall vom sind aber ebenfalls denkbar. Ressourcen lassen sich, wie auch im herkömmlichen Abruf im Browser nur durch die Repräsentationen Web, miteinander verlinken. der Response, die im XML- anstatt im HTML-Format dargestellt wird. Der Zugriff auf die API erfolgt ganz einfach durch das HTTP- Dem Routing-System von Symfony kommt bei der Umsetzung Protokoll. Die verschiedenen Methoden des Protokolls codieren die einer REST-API eine wichtige Rolle zu. Durch die Routing-Regeln Operationen auf der Anwendungsebene. Wird beispielsweise per wird in erster Linie festgelegt, welchen URI eine Ressource be- GET auf eine Ressource zugegriffen, weiß der Server, dass ein Lese- kommt, mit welcher HTTP-Methode darauf zugegriffen werden darf vorgang durchgeführt werden soll – derselbe Request mit der und welcher Actioncontroller den Request verarbeitet. DELETE-Methode würde die Ressource hingegen löschen (mehr dazu unter [3] ). Eine einfache Routing-Regel booklist: # Darstellung einer Liste mit dem Buchbestand url: /booklist.:sf_format Tools zum Testen von REST-APIs class: sfRequestRoute REST-basierte Schnittstellen lassen sich nicht direkt im Browser ent- param: { module: book, action: list, , sf_format: html } wickeln oder testen, da sich die HTTP-Methoden für den Request nicht requirements: { sf_method: GET, sf_format: (?:xml|json|html) } festlegen lassen und auch kein direkter Zugriff auf weitere Parameter Listing 1 des HTTP-Requests besteht. Abhilfe schafft das Programm „RESTClient“ (http://bit.ly/RESTClient) oder die Firefox-Erweiterung „RestTest“ (http://bit.ly/RESTTest). Im Zusammenhang mit REST-APIs spielt insbesondere der sf_for- mat-Parameter eine wichtige Rolle. Durch ihn wird das Format 1 © yeebase media 2009. Veröffentlichung und Vervielfältigung nur mit Genehmigung der yeebase media GbR. http://t3n.yeebase.com
  • 2. bestimmt, in dem die Ressource an den Client ausgeliefert wird. Der bere Trennnung zu den Front- und Backend-Applikationen zu ha- Standardwert ist HTML, erlaubt sind in diesem Beispiel aber auch ben, die in fast jedem Symfony-Projekt vorhanden sind. XML oder JSON. Alternativ lässt sich das Request-Format auch direkt Eine neue API-Applikation samt Book-Modul ist dank der Kom- in der Action festlegen (Listing 2), allerdings ist es eleganter, das mandozeilentools schnell angelegt: direkt über den URI zu tun. API-Applikation genieren Request-Format im Controller setzen $ symfony generate:app api $ symfony generate:module api book $request->setRequestFormat('xml'); Listing 3 Listing 2 Für das Book-Modul das Scaffolding zu verwenden, ist durchaus Durch den sf_method-Parameter wird festgelegt, mit welchen Me- möglich, aber nicht unbedingt sinnvoll: Es werden dann zwar alle thoden eine Ressource aufgerufen werden kann. Dies kann beson- nötigen Methoden im Actioncontroller angelegt, diese gehen aber ders bei komplexeren APIs praktisch sein – zum Beispiel lässt sich davon aus, dass die Daten zum Anlegen oder Ändern von Daten- so der Request für eine Ressource per DELETE-Methode unterbin- sätzen von den ebenfalls generierten (HTML-)Formularen in den den. Templates stammen. Für die API allerdings müssen diese stattdes- Für komplexere Requests mit mehr Parametern ist es darüber sen aus den HTTP-Bodys extrahiert werden, wo sie im XML-Format hinaus sogar möglich, bereits im Routing eine Validierung der GET- an die Schnittstelle übertragen werden. Parameter per regulärem Ausdruck vorzunehmen. Bei einer dedizierten Applikation für die API kann auch die View- Konfiguration geändert werden (Listing 4): Ein Layout wird jetzt nicht mehr benötigt, da die Templates aus reinem XML bestehen. Außerdem wird auch der standardmäßige Content-Type ange- passt. Anpassungen an der view.yml für die API default: http_metas: content-type: text/xml has_layout: off Listing 4 Symfony und das Doctrine-ORM stellen für das Routing einen nütz- lichen Shortcut bereit: Der Aufbau von Symfony gliedert sich in eine Plattform und das darauf aufset- zende Framework. Shortcut in der routing.yml book: Die Bücherliste kann außer im HTML-Format auch als XML- oder class: sfDoctrineRouteCollection options: { model: Book } JSON-Repräsentation angefordert werden. Dazu müssen für jedes Format eigene Templates angelegt werden und Symfony wählt auf Listing 5 Basis des gesetzten sf_request-Parameters das Passende aus. Aus- schlaggebend ist hierbei die Dateiendung: listSuccess.php für eine Diese Regel wird zu einer Reihe REST-konformer Routen aufgelöst, standardmäßige HTML-Repräsentation, listSuccess.xml.php für ähnlich wie jener in Listing 1, die man sich in der Zusammenfassung XML und listSuccess.json.php für JSON. auch durch die Kommandozeile anzeigen lassen kann: Symfony liefert standardmäßig nur die HTML-Repräsentation mit einem Layout aus, das bei JSON oder XML natürlich entfällt. Routen in der API Außerdem kümmert sich das Framework selbstständig um den kor- $ symfony app:routes rekten Content-Type (text/xml bzw. text/x-json) im HTTP-Header. >> app Current routes for application Name Method Pattern book GET /book.:sf_format Komplexer: Datenmanipulation book_new GET book_create POST /book/new.:sf_format /book.:sf_format book_edit GET /book/:id/edit.:sf_for Mit den beschriebenen Funktionen hat man im Prinzip bereits alles book_update PUT /book/:id.:sf_format zusammen, was man braucht, um eine sehr einfache API zum Aus- book_delete DELETE /book/:id.:sf_format lesen und Bereitstellen von Daten zu implementieren. Anspruchs- book_show GET /book/:id.:sf_format voller wird es jedoch, wenn die API nicht nur Daten auslesen, Listing 6 sondern auch ändern, löschen oder erstellen soll. Ein weitaus kom- plexeres Anwendungsszenario ist daher die Implementierung einer Diese Routen verweisen auf die jeweiligen Methoden (new, create, Schnittstellenfunktion, mit der ein Verleger neue Bücher direkt aus edit, update usw.) im Actioncontroller des Book-Moduls, die später dem eigenen Warenwirtschaftssystem in das Shop-System über- implementiert werden müssen. tragen kann. Aus einer „lesenden“ wird so eine „schreibende“ API. Für den Einsatz innerhalb einer API sollten die „Edit“- und Je umfangreicher eine API wird, desto sinnvoller kann es sein, „New“-Methoden nicht implementiert werden beziehungsweise diese in eine eigenständige Applikation auszulagern um eine sau- eine Fehlermeldung werfen, da eine GET-Methode niemals in der © yeebase media 2009. Veröffentlichung und Vervielfältigung nur mit Genehmigung der yeebase media GbR. http://t3n.yeebase.com 2
  • 3. Lage sein sollte, Daten auf einem Server in irgendeiner Weise zu koppelt dabei ein Datenbankobjekt direkt mit dem ID-Parameter in ändern (oder zu erstellen). Das ist ausschließlich den idempotenten der URL, sodass man im Controller darauf zugreifen und sich eigene Methoden PUT, POST und DELETE vorbehalten. Queries weitgehend sparen kann. Wird kein Datensatz mit der ge- wünschten ID gefunden, wirft Symfony einen 404-Fehler. Die Im- Authentifizierung durch API-Keys plementierung der Controller-Methoden geht daher schnell von der Hand. Um die Dateilansicht eines Buchs anzuzeigen, reicht eine Natürlich sollen nur autorisierte Benutzer Datensätze erstellen oder Zeile im Controller: ändern dürfen. Bevor also eine Aktion ausgeführt wird, muss sich der Benutzer zunächst gegenüber der API authentifizieren. Eine Detailansicht eines Buchs Möglichkeit dazu ist die Verwendung von API-Keys. Der API-Key kann im HTTP-Header (zum Beispiel als „X-ApiKey“) mitgeschickt // HTTP-Request: GET /book/[id] HTTP/1.1 public function executeShow(sfWebRequest $request) { werden und dient als Ersatz für die übliche Benutzernamen/Pass- $this->book = $this->getRoute()->getObject(); // $this->book is now available wort-Kombination (sinnvollerweise sollten Requests an die API in in the template diesem Fall per HTTP/S gesichert werden). Die Authentifizierung } kann in Symfony als Filter (Listing 7) implementiert werden, der vor Listing 9 dem Abarbeiten des eigentlichen Requests im Controller durch- laufen wird und in der filter.yml aktiviert werden muss. Ein Request für denselben URI mit der DELETE-Methode wird REST- konform zur Delete-Methode geroutet: API-Filter Klasse class apiFilter extends sfFilter { Ein Buch löschen public function execute($filterChain) { if ($this->isFirstCall()) { // HTTP-Request: DELETE /book/[id] HTTP/1.1 $request = $this->getContext()->getRequest(); public function executeDelete(sfWebRequest $request) { $session = $this->getContext()->getUser(); $book = $this->getRoute()->getObject(); // Get API-Key from HTTP-Header // User allowed to delete this Book? If not, stop execution and send HTTP- $apikey = $request->getHttpHeader('X-ApiKey'); Statuscode 403 // Select user from database by given API-Key $this->checkPermission($book); $userprofile = Doctrine::getTable('User')->findOneByApikey($apikey); // ...User has Permission, let's delete this Book // Throw an error if user cannot be found... $book->delete(); jeHTTPError::forwardUnless($userprofile, 401, 'Invalid or missing API-Key'); } // ...or save the user in the session $session->setAttribute('user',$userprofile); Listing 10 } // Execute next filter in filter symfonys filter chain $filterChain->execute(); Mit den POST- und PUT-Methoden wird ein neues Buch angelegt // Code to execute AFTER the action execution, before the rendering beziehungsweise ein bestehendes Buch geändert. Die dazu erfor- // Delete User-Session after every API-Request derlichen Daten werden als XML im HTTP-Body übertragen und session_unset(); session_destroy(); müssen daher ausgelesen und geparst werden. Hierzu kann man } im lib-Verzeichnis in einer Klasse eine einfache Methode (Listing 11) } implementieren, die bei Gebrauch durch den Autoload-Mechanis- Listing 7 mus von Symfony inkludiert wird. Dieser Filter lädt zum einen das Benutzerobjekt anhand des API- Auslesen der XML-Nutzlast Keys im Header aus der Datenbank und speichert es in der Symfony- class Tools { Benutzersession, sodass es überall im Code zur Verfügung steht. Ist public static function getRequestBody () { der API-Key nicht korrekt, wird stattdessen eine Fehlermeldung mit $stream = fopen("php://input", "r"); $data = stream_get_contents($stream); entsprechendem HTTP-Statuscode gesendet. Zum anderen muss fclose($stream); die Session wieder gelöscht werden, nachdem der Request abge- return simplexml_load_string($data); arbeitet wurde. REST ist per Definition zustandslos, das heisst eine } } „klassische“ Session wird nicht gespeichert. Für das Error-Handling kann wie in Listing 7 das jeHTTPError- Listing 11 Exception-Plugin genutzt werden, welches das Symfony-Error Handling um die Fähigkeit erweitert, beliebige HTTP-Statuscodes Ein neues Buch lässt sich ebenfalls sehr einfach erzeugen: und Fehlermeldungen in der Response zurückzugeben. Gerade im Zusammenhang mit REST ist das eine praktische Sache. Das Plugin Ein neues Buch anlegen lässt sich mit Hilfe des CLI schnell installieren: // HTTP-Request: POST /book HTTP/1.1 public function executeCreate(sfWebRequest $request) { Plugin installieren $data = Tools::getRequestBody(); $book = new Book(); $book->saveBook($data); // Save Book in the Model $ symfony plugin:install jeHTTPErrorExceptionPlugin $this->getResponse()->setStatusCode(201); $this->getResponse()->setHttpHeader('Location', Listing 8 $request->getHost().'/book/'.$book->get('id')); } Der Controller des Book-Moduls Listing 12 In Listing 5 werden Routen auf die Index-, Show-, Create-, Update-, und Delete-Methoden des Book-Controllers erzeugt, die imple- In dieser Methode werden die Daten zunächst aus dem Request- mentiert werden müssen. Die sfDoctrineRouteCollection-Klasse Body extrahiert und an das Model übergeben, wo das neue Buch 3 © yeebase media 2009. Veröffentlichung und Vervielfältigung nur mit Genehmigung der yeebase media GbR. http://t3n.yeebase.com
  • 4. dann angelegt wird. Wichtig ist, dem Client im Response per HTTP- Statuscode mitzuteilen, dass die Ressource erzeugt wurde („201 – Created“) und deren (neue) URI im Location-Header anzugeben. Analog dazu funktioniert das Editieren eines Buchs: Ein bestehendes Buch editieren // HTTP-Request: PUT /book/[id] HTTP/1.1 public function executeUpdate(sfWebRequest $request) { $data = Tools::getRequestBody(); $book = $this->getRoute()->getObject(); // User allowed to edit Book? If not, stop execution, send HTTP-Statuscode 403 $this->checkPermission($book); $book->saveBook($data); } Listing 13 Für alle genannten Methoden müssen natürlich auch die jeweiligen (XML-)Templates angelegt werden, um einem Client das ge- wünschte Feedback – zum Beispiel in Form einer Statusmeldung – geben zu können. Für die Validierung der Benutzerdaten bringt Symfony eine Reihe von Standard-Validatoren mit, die allerdings primär zur Verwendung mit dem Formular-Framework gedacht sind. Noch einfacher lassen sich alternativ die Validatoren des Doc- trine-ORMs [4] verwenden, die man bereits in der Schema-Datei konfigurieren kann und die die Daten noch auf der Anwendungs- ebene unmittelbar vor dem Speichern in der Datenbank validieren. Zusammenfassung Mit Hilfe des Symfony-Frameworks lassen sich REST-basierte Schnittstellen sehr sauber und vergleichsweise einfach implemen- tieren. Dieser Artikel zeigt nur einen von vielen Ansätzen, der sich aber grundsätzlich auch für umfangreiche APIs eignet – selbst wenn für den produktiven Einsatz noch einige Aspekte tiefer ausgearbei- tet werden müssten. ↔ Links und Literatur ↗ Softlink 2426 [1] Offizielle Website des Symfony-Projekts: http://www.symfony- project.org/ [2] Wikipedia-Eintrag zu REST: http://de.wikipedia.org/wiki/ Representational_State_Transfer [3] OIO: REST Web Services: http://www.oio.de/public/xml/rest- webservices.pdf [4] Doctrine Data Validation: http://www.doctrine-project.org/ documentation/manual/1_1/en/data-validation Der Autor Daniel Haller ist bei der Frankfurter Agen- tur BlueMars als Technischer Projektma- nager und Web Developer tätig. Mit REST- basierten APIs hat er sich im Rahmen seiner Diplomarbeit zum Media System Designer in Darmstadt beschäftigt. Er ist begeister- ter Anwender des Symfony-Frameworks. © yeebase media 2009. Veröffentlichung und Vervielfältigung nur mit Genehmigung der yeebase media GbR. http://t3n.yeebase.com 4