Routing & RESTful Rails

Dieser Artikel ist eine Zusammenfassung des Vortrages “Routing and REST”, den ich an der TFH-Berlin in der Lehrveranstaltung RUBY ON RAILS gehalten habe. Es wird eine kleine Einführung in die Prinzipien REST-konformer Webanwendungen gegeben. Weiterhin wird kurz darauf eingegangen, wie REST im Open-Source-Web-Framework Ruby On Rails umgesetzt wird.

Webservices bezeichnen Schnittstellen, über die Anwendungen in verteilten Systemen Daten austauschen können. Über das Internet (oder ein Intranet) kann so auf entfernte Datenbestände zugegriffen werden. Die bekanntesten Technologien sind:

  • RPC ( Remote Procedure Call )
  • SOAP ( Simple Object Access Protocol )
  • REST ( Representational State Transfer )

Ruby On Rails setzt verstärkt auf REST. Seit der Version 2.0 ist SOAP nicht mehr als Standard im Rails-Framework vorhanden, sondern muss bei Bedarf hinzugefügt werden. Ersetzt wurde das SOAP-Basierende “Action Web Service” durch “Active Resource” für REST. In einem Artikel auf Computerwoche.de erklärte David Heinemeier Hansson, Co-Autor von Agile Web Development with Rails, dass Rails nicht technologieneutral sei, sondern eine Wahl treffe. Diese sei nicht SOAP, “Die Antwort ist REST.”

Das Synonym REST steht für Representational State Transfer. REST ist keine neue Technologie, sondern stellt Regeln für ein ressourcenorientiertes Softwaredesign auf Basis von HTTP und Uniform Resource Identifier (URI) auf. Die Wichtigsten Regeln sind:

  • Aufteilung in Ressourcen
  • Addressierbarkeit (URIs)
  • Einheitliche Schnittstelle (HTTP)
  • Anwendungszustand im Client
  • Idempotenz
    (mehrmalige Anweisungen führen zum selben Ergebnis)
  • Hypermedia
    (Ressourcen verlinken andere Ressourcen)

In einer REST-konformen Anwendung wird der gesamte Datenbestand, der als Webservice zur Verfügung stehen soll in Ressourcen aufgeteilt. Eine Ressource kann alles sein, was verlinkt werden kann. Der Datentyp spielt dabei keine Rolle. Jede Ressource bekommt (mindestens) einen eindeutigen URI und ist damit adressierbar.

Als einheitliche Schnittstelle wird der Funktionsumfang jeder Ressource auf die HTTP-Standard-Funktionen beschränkt. Falls dieser Funktionsumfang für eine Ressource nicht ausreichen sollte, muss das Softwaredesign überdacht werden und die betroffene Ressource in weitere Ressourcen aufgeteilt werden. Die wichtigsten HTTP-Methoden sind POST, GET, PUT, DELETE mit denen sich alle CRUD-Anweisungen (Create, Read, Update, Delete) ausführen lassen. Weiterhin stehen Methoden wie HEAD für die Metadatenabfrage und OPTION, für die Abfrage welche Methoden für die Ressource implementiert sind, zu Verfügung.

Als ein Beispiel für eine ressourcenorientierte Anwendung könnte eine Online-Shop dienen. Folgende Ressourcen werden als Webservice angeboten:
A: http://www.example.com/products/
B: http://www.example.com/products/1

Mit dem URI (A) wird eine Liste aller Produkte adressiert. Mit der dem URI (B) ein konkretes Produkt.

Auf (A) kann mit den HTTP-Methoden GET und POST zugegriffen werden. GET liefert eine Liste mit allen Produkten. Diese Liste enthält u.a. URIs zu allen konkreten Produkte. POST legt ein neues Produkt an und erstellt damit eine neue Ressource.

Auf (B) kann mit den HTTP-Methoden GET, PUT und DELETE zugegriffen werden. GET liefert als Response das konkrete Produkt, mit PUT kann das Produkt verändert werden und mit DELETE wird das Produkt und damit die Ressource gelöscht.

In einer REST-konformen Anwendung gibt es zwei Arten von Zuständen. Den Anwendungszustand und den Ressourcenzustand.

Der Anwendungszustand wird Client-Seitig gehalten. Die Serveranwendung nimmt keine Zustände an. Das bedeutet, jeder HTTP-Request an eine Ressource steht für sich. Die Response vom Server kann den Client jedoch in eine neuen Anwendungszustand führen.

POST, PUT und DELETE-Requests verändern den Ressourcenzustand. PUT- und DELETE-Zugriffe müssen idempotent sein. Das bedeutet, dass ein mehrmaliges Ausführen desselben Requests immer zum selben Ergebnis im Ressourcenzustand führt. Aus diesem Grund ist gerade bei PUT ist darauf zu achten, dass die Veränderungen nicht relativ zum Datenbestand stattfinden.

Durch die Zustandslosigkeit des Servers muss sich der Client unter Umständen bei jedem Request authentifizieren. Dieser Fakt bringt einige Sicherheitsüberlegungen mit sich.

Verantwortlich für das Routing in Rails ist das Routing-System. Ein beliebiger Client stellt einen HTTP-Request an die Rails-Applikation. In der Rails-Applikation nimmt das interne Routing System die URI entgegen und überprüft die Syntax auf Korrektheit. Dafür zuständig ob die Methoden existieren und ihr Aufruf zu korrekt gerouteten Verweiszielenführen, ist ein Eintrag in der Routing-Datei config/routes.rb :map.resources :products

Wird die URL vom Routing-System gefunden wird der passende Controller instanziiert und die geforderte Action-Methode aufgerufen. Die Methode führt ihre geforderten Prozesse aus und bezieht ggf. neue Daten aus der Datenbank. Die Daten werden aktualisiert und mit einer Response die View im Web-Browser neu gerendert.

REST-konforme Anwendugen in Rails zeichnen sich dadurch aus, dass die Action-Methode nicht explizit in der URI angegeben wird, sondern das Routing-System auf Grund des HTTP-Verbs entscheidet welche CRUD-Anweisung ausgeführt werden soll.

Beispiel:

Die explizite Vergabe der SHOW-Action in einem Link ist nicht Rest-Konform

link_to “Show”, :action=>”show”, :id=>”3”
<a href=”/products/show/3″>Show</a>

Rest-Konform ist das weglassen der SHOW-ACTION womit die Rails-Anwendung das HTTP-Verb auswertet und die Action ausführt:

link_to “Show”, products_path(product)
<a href=”/products/3″>Show</a>

Da der Web-Browser keine PUT und DELETE Actions kennt, löst Rails dieses Problem mit dem Key method in der html-Hash der form_for – Methode:

form_for(:project, :url => product_path(@product),
:html => { :method => :put }) do |f| …

wird zu:

<form action=”/products/1″ method=”post”>
<div style=”margin:0;padding:0″>
<input name=”_method” type=”hidden” value=”put” />
</div>

Rails generiert ein Hidden-Field method mit der zu verwendenden HTTP-Methode put. Das Routing-System wertet das Feld aus und aktiviert die zugehörige Action update.

Mehr zum Thema:

Buch: WebServices mit REST (Leonard Richardson & Sam Ruby - O’Reilly Verlag): Eine Einführung in REST auf 512 Seiten! Wer jedoch schon etwas Wissen mitbringt, kann locker mit Kapitel 8 beginnen… und auch alle Anderen können öfters mal vorblättern!

RESTful Rails Development (RalfWirdemann und Thomas Baustert): Kostenlos als PDF in drei Sprachen: http://www.b-simple.de/documents

Special thanks an Konrad!

Add Comment!




Security Code: