Artikel

 
April 2010 | Artikel

RESTFul JSF: Brainstorming

(Link zum Artikel: http://www.it-republik.de/jaxenter/artikel/3040)

Die FacesTales-Kolumne

Text: Lars Röwekamp und Matthias Weßendorf
  • Teilen
  • kommentieren
  • empfehlen
  • Bookmark and Share
In den letzten Jahren macht das Akronym REST (Kurzform für Represental State Transfer) in der Web- und Web-Service-Community vermehrt die Runde. Nicht wenige sehen REST als Allheilmittel in dem immer stärker wachsenden Problemdschungel. Was bedeutet dies nun aber für JSF? Sind die letzten Tage unserer Kolumne gezählt? Um es gleich vorwegzunehmen: JSF mit REST zu vergleichen, macht genau soviel Sinn wie ein Vergleich von Äpfel und Birnen. Aber es bleibt ja immer noch die Alternative "gemischter Obstsalat".

REST aus 10 000 m

Der Begriff REST wurde bereits im Jahr 2000 von Roy Fielding im Rahmen seiner Dissertation geprägt. Fielding beschreibt hier eine Architektur für Webanwendungen, die auf der Grundidee basiert, dass sich eine Anwendung vollständig durch ihre Ressourcen und den möglichen Manipulationen auf ihnen beschreiben lässt. Jede Ressource wird dabei durch ein eindeutiges URI beschrieben. Zum Zugriff auf die Ressourcen werden einfache HTTP-Aufrufe verwendet, die sich je nach Art des Zugriffs – Anlegen, Lesen, Ändern oder Löschen der Ressource – in der verwendeten Methode unterscheiden (GET, POST, PUT oder DELETE). Mittlerweile bieten viele öffentliche Dienste ein entsprechendes REST-API an. Als Beispiel soll an dieser Stelle das Twitter-REST-API herangezogen werden, das zugegebenermaßen an der einen oder anderen Stelle nicht zu 100 % dem reinen REST-Paradigma entspricht.

Die Liste aller Status der eigenen Twitter-Freunde lässt sich via GET - http://twitter.com/statuses/friends_timeline.format erfragen. Möchte man dagegen seinen aktuellen Status committen, gelingt dies nach einer vorherigen Authentifizierung über POST – http://twitter.com/statuses/update.format. Wie nicht anders zu erwarten, kann ein einmal angelegter Status durch den Aufruf von POST oder DELETE - http://twitter.com/statuses/destroy/id.format am Ende auch wieder gelöscht werden. Spätestens an dieser Stelle fällt ein Bruch mit dem reinen REST-Paradigma auf (POST ist neben DELETE erlaubt und die gewünschte Aktion – destroy – ist im URL enthalten). Dieser Bruch trägt der Tatsache Rechnung, dass nicht alle http-Clients in der Lage sind, ein DELTE bzw. PUT abzusetzen. Das .format ist übrigens optional und steht für den gewünschten Rückgabetyp (XML, JSON, RSS, ATOM). Eine kleine Anmerkung am Rande: Auch die beiden Autoren der Kolumne twittern fleißig (@mobileLarson/Lars Röwekamp und @mwessendorf/Matthias Weßendorf).

JSF und REST?

So weit, so gut. Aber was bedeutet das in Bezug auf JSF? Zunächst einmal fällt auf, dass REST optimal für bookmarkable URLs geeignet zu sein scheint. Könnte dies also die Lösung für eines der großen JSF-Probleme – die angeblich fehlende Bookmark-Fähigkeit – sein? Die Antwort ist ein klares "Nein". Um dies zu verstehen, muss man sich noch einmal den Hauptfokus beider Welten vor Augen halten: JSF ist ein UI-zentriertes Webframework. REST dagegen fokussiert sich auf den Service Layer einer Anwendung und stellt somit eher eine leichtgewichtige Alternative zum schwergewichtigen, SOAP-basierten Web Service dar. Das Einführen von RESTful URLs zum Aufruf eines JSF-basierten UI, nur um so ein Bookmark setzen zu können, macht also nicht wirklich Sinn. Für diesen Zweck gibt es weitaus bessere Lösungen (siehe hier oder hier) sowie ab JSF 2.0 die Möglichkeit zur direkten Generierung eines entsprechenden Links mithilfe der beiden neuen Komponenten und (siehe hier, Abschnitt 2.5.6 "Bookmarkability").

Macht dann eine gemeinsame Verwendung von JSF und REST überhaupt einen Sinn, und wenn ja, wie könnte sie aussehen? Prinzipiell sind zwei, eigentlich sogar drei Szenarien denkbar. Zum einen kann eine JSF-Anwendung als Consumer einen RESTful Service nutzen und das Ergebnis im Anschluss visualisieren. Zum anderen kann ein Service, der innerhalb einer JSF-Anwendung genutzt wird, via REST-API auch Dritten – als Partner-API – zur Verfügung gestellt werden. In diesem Fall wäre die JSF-Anwendung der REST Service Provider. Das dritte Szenario ist eigentlich nur eine spezielle Variante des ersten, bei dem der Zugriff auf ein externes REST-API via JSF-Komponente gekapselt und so für andere JSF-Anwendungen wiederverwendbar zur Verfügung gestellt wird.

JSF REST Service Consumer

Stellen wir uns einmal folgende Aufgabenstellung vor: Ein Twitter-Client soll auf Basis von JSF implementiert werden. Der einzige Unterschied zu einer "normalen" JSF-Anwendung besteht somit eigentlich nur darin, dass die Ressourcen – die Twitter-Status – nicht aus einer Datenbank, sondern aus einem externen Dienst via REST-API herangezogen werden müssen. Das Ganze lässt sich hervorragend in einem eigenen Service innerhalb des Service Layers der JSF-Anwendung kapseln. Der Wrapper-Service greift via HTTP (get, post, put oder delete) auf das entsprechende Twitter-API zu und parst im Anschluss den Response bzw. lässt ihn via Converter Library automatisch in die gewünschten Java-Objekte überführen. Der Zugriff auf den Twitter-REST-Service ließe sich über die HttpURLConnection realisieren. Als Converter Library könnte im Fall einer XML-Antwort JAXB und für JSON ein entsprechender JSON Marshaller verwendet werden. Noch einfacher geht der Zugriff, wenn der externe Service eine WADL (Web Application Description Language) zur Verfügung stellt. In diesem Fall kann der Client automatisch generiert werden.

JSF REST Service Provider

Soll ein interner Service einer JSF-Anwendung nicht nur zur Generierung des UI, sondern auch als REST-API nach außen zur Verfügung gestellt werden, bietet es sich an, einen zweiten Einstiegspunkt in der web.xml der Anwendung zu definieren, um so das FaceletServlet inkl. JSF LifeCycle für alle REST Calls vollständig zu umgehen. Mittlerweile existiert in der Java-Welt mit dem JSR-311 (JAX-RS API) ein Standard für die Umsetzung REST-basierter Services und mit Jersey, Apache CXF und RESTEasy finden sich bereits erste Implementierungen. Das folgende kurze Listing zeigt den Aufbau des Service-Endpoint-Interfaces eines Kundeninformationssystems gemäß JSR-311:

  1. @Path("/")
  2. @Produces("application/xml")
  3. public interface CustomerRESTEndpoint {
  4. @GET
  5. @Path("/customers/")
  6. public Response getAllCustomers ();
  7. @GET
  8. @Path("/customers/{customerNo}")
  9. public Response getCustomer (@PathParam("customerNo ") String customerNo);
  10. ...
  11. }
Ausblick

JSF und REST sind zwar von Haus aus nicht unbedingt optimal aufeinander eingestimmt, dies bedeutet aber nicht, dass sie nicht doch in Kombination sinnvoll genutzt werden können. Eine JSF-Anwendung kann sowohl externe REST Services konsumieren als auch selbst einen internen Service via REST-API nach außen zur Verfügung stellen. In der nächsten Ausgabe zeigen wir die bisher noch fehlende dritte Variante: Eine JSF-REST-Komponente am Beispiel von Twitter.

Lars Röwekamp ist Geschäftführer der OpenKnowledge GmbH und berät seit mehr als 10 Jahren Kunden in internationalen Projekten rund um das Thema Enterprise Computing (Twitter: @mobileLarson).

Matthias Weßendorf arbeitet für die Oracle Corp. an ADF Faces und Apache Trinidad. Seit 2004 ist er PMC von Apache MyFaces. Matthias hat an verschiedenen internationalen Konferenzen als Redner teilgenommen (Twitter: @mwessendorf).

  1. http://www.ics.uci.edu/~fielding/pubs/dissertation/top.htm
  2. http://restfaces.dev.java.net/
  3. http://ocpsoft.com/prettyfaces/
  4. http://jcp.org/en/jsr/detail?id=314
  5. http://code.google.com/p/jsonmarshaller/
  6. https://jersey.dev.java.net/
  7. http://cxf.apache.org/
  8. http://jboss.org/resteasy/

andere Artikel dieser Serie


Anzeige

Kommentare

Gravatar Trepper 26.04.2010
um 11:25 Uhr
"REST dagegen fokussiert sich auf den Service Layer einer Anwendung und stellt somit eher eine leichtgewichtige Alternative zum schwergewichtigen, SOAP-basierten Web Service dar."
Das ist dann wohl REST aus der JSF-Perspektive. Die REST-Prinzipien lassen sich auch gut für Browser-orientierte Webanwendungen nutzen, auch wenn es mit HTML 4 noch ein paar Einschränkungen gibt. Für genau diese Einschränkungen ist JSF ein Workaround, aber die JSF-Architektur ist Anti-REST und widerspricht grundlegend den Prinzipien des Webs.

Schlanke REST-Dienste und Ajax im Browser ist vom Ansatz viel sauberer und skalierbarer als JSF - und wenn man schon einen Workaround mit Client-Zustand auf dem Server braucht, kann man besser Wicket nehmen.
#zitieren
Gravatar Herr Rabe 17.05.2010
um 17:18 Uhr
Hallo,

Ein viertes Szenario wäre ebenfalls denkbar, in dem lediglich die Darstellungskomponenete (EL, Taglibs und Renderer) der JSF im Kontext eines RESTful HTML Service verwendet wird.
Hiermit würde natürlich auf die ganzen Stateful Features der JSF verzichtet, es stünde aber immernoch ein mächtiges Präsentationsmittel zur Darstellung zur Verfügung.

Ich habe hierzu in meinem Blog eine tiefere Betrachtung beschrieben, wie soetwas aussehen könnte: http://creativecoding.blogspot.com/2010/05/restful-java-server-faces-und-bist-du.html
#zitieren

Anzeige

zurück zum Seitenanfang