Ginkgo-API: Technische Aspekte

2 Dez

Nachdem ich mich ausreichend in Themen wie API-Erstellung, Authentifizierung, Ressourcenverteilung und Versionierung eingearbeitet habe, gilt es nun, diese theoretischen Erkenntnisse mit den Möglichkeiten, die Rails bietet, abzugleichen.

Rails ist natürlich in dem Sinne „ready for REST“, dass durch ein einfaches respond_to :json, :xml in Controllern und Anpassungen am Routing-Schema Abfragen als JSON/XML funktionieren. Solch ein „out-of-the-box“-Service ist schön, stößt aber für eine saubere REST-Schnittstelle an seine Grenzen:

Repräsentationen sind serialisierte Datenbankobjekte
Über to_json werden im Standardfall serialisierte Datenbankobjekte geliefert. Ich möchste aber meine Repräsentationen selbst definieren, inkl. Feldernamen, mit verschachtelten weiteren Ressourcen und Feldern, die gar nicht in der Datenbank vorkommen oder von anderen Operationen abhängen.

Teilweise kann das in fast akribischer Kleinarbeit durch Parseroptionen  (:include, :exclude, :only, :method, ..) erreicht werden, einige Dinge gehen aber einfach nicht. Der Artikel If you’re using to_json, you’re doing it wrong  verdeutlicht dies sehr schön.

Fehlende Hyperlinks in Repräsentationen
Standardmäßig generierte Repräsentation enthalten keinerlei Links zu anderen Ressourcen.

Die Lösung für diese Probleme ist die Erstellung von View-Templates für JSON/XML (ähnlich den *.erb-Dateien für HTML-Ausgaben). Mehrere Projekte beschäftigen sich damit:

Restfulie

Restfulie ist ein ausgereiftes und aktives Projekt, das auch RESTful-Clientbibliotheken für Ruby, Java, C#, Python und JavaScript anbietet.

Keine besonderen Änderungen am Controller sind notwendig:

class Api::V1::EventsController
respond_to :json, :xml

def show
@event = Event.find(params[:id])
respond_with @event
end

end

Der Aufbau der Repräsentationen wird in *.tokamak-Templates definiert (views/api/events/show.tokamak):

event {
link :self, event_url
name @event.name

}

Ergibt folgendes JSON:

{ „event“:

„name“:“Mein erstes Event“,

{„link“:[        {„rel“:“self“, „href“:“http://127.0.0.1:3000/api/events/4ed795fb2a936f2ced000001″, „type“:“application/json“}]

}}

Templates können auch ineinander verschachtelt werden.

Rabl

Rabl hat in den Templates fast die gleiche Syntax wie in Restfulie, unterstützt aber kein Hyperlinks.

Roar

Roar ist ein kleineres Projekt, das den Aufbau der Repräsentationen nicht in renderbaren Templates definiert sondern über Ruby-Klassen („Representer“).

class ArticleRepresenter
include Roar::Representer::JSON

property :title
property :id

link :self do
article_url(represented)
end
end

ArticleRepresenter.serialize(Article.find(4711)) ergibt

{ „article“: {
„title“:  „Lonestar Beer“,
„id“:     4711,
„links“:[
{ „rel“:  „self“,
„href“: „http://articles/lonestarbeer“}
]}
}

Restfulie ist das bei Weitem etablierteste Projekt und biete alle benötigten Funktionalitäten (soweit ich das heute einschätzen kann).

Noch eine Anmerkung zur Frage aus dem letzten Meeting, ob die ginkgoGUI später nicht auch die API nutzen kann:

Das wird nicht klappen und würde zu einer unwartbaren Vermischung von GUI und API führen. Alle Artikel, die ich bis jetzt gelesen habe basieren auf einem eigenen Satz von Controllern für die API (und sogar auch für jede API-Version! Julian hatte mir mal einen schönen Blogeintrag geschickt: Versioning you API). Trotzdem sollte vorhandener Controller-Code, soweit möglich, wiederwerwendet werden (ggf. mit include…).
In diesem Kontext vermisse ich in Rails eigentlich ein bisschen das Service-Layer, das ich von Grails kenne. In Grails sind Services zustandslose Singletons, die von überall aus (nur nicht aus Views) nutzbar sind. Hier kann man sehr schön gemeinsam genutzte Business-Logik unterbringen.

Meinungen, Tipps und Erfahrungen zu den oben genannten Sachen sind gerne willkommen. Ich bin ja noch nicht so lange Rubyaner.

Schreibe einen Kommentar

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

WordPress.com-Logo

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

Twitter-Bild

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

Facebook-Foto

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

Google+ Foto

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

Verbinde mit %s

%d Bloggern gefällt das: