![]() |
|
URL dieses Artikels:
zu Ausgabe:
02.2002
Kalorien sparen
Web Services mit Perl und SOAP::Lite
von Rolf Schaufelberger
Mittlerweile existieren über 70 Toolkits zur Realisierung von Web Services. Natürlich hat auch die Perl-Fraktion einiges zu bieten. Der folgende Artikel beschreibt die Implementierung von Web Services mit dem Perl-Modul SOAP::Lite. Das Lite im Namen weist nach Aussage des Entwicklers Paul Kulchenko darauf hin, dass bei dessen Verwendung nur eine geringe Anzahl Kalorien verbraucht werden.
Im Zusammenhang mit SOAP und Web Services ist meist nur von Java und .NET als Entwicklungsumgebungen die Rede. Während für einige die .NET-Welt aus Glaubensgründen ausscheidet, gestaltet sich die Entwicklung mit Java recht aufwändig. Da müssen Pakete im dreistelligen MB-Bereich geladen und anschließend konfiguriert werden. So stellte der Autor des Beitrags Bestell Service (XML Magazin 01.2002) in seinem Fazit fest, dass der meiste Aufwand in der Bereitstellung und Konfiguration der Umgebung liegt [1]. Genau hier verspricht das Open Source-Toolkit SOAP::Lite Abhilfe, trägt es den Lite-Gedanken doch schon in seinem Namen. Möglich ist dies durch eine Reihe von Weiterentwicklungen, welche Perl in den letzten Jahren erfahren hat, die jedoch, wie ich in einigen Gesprächen feststellen musste, weithin gar nicht bekannt sind. Perl kämpft mit dem verbreiteten Vorurteil, nur für einfache Skripte und CGI-Programmierung zu taugen. Da die Basics einfach zu erlernen sind, kann damit praktisch jeder programmieren, was sich dann wieder negativ auf die Qualität der Programme auswirkt. Mittlerweile hat sich die Perl-Gemeinde des Themas Idiotic Perl angenommen und versucht hier Aufklärungsarbeit zu leisten. An erster Stelle der erwähnten Weiterentwicklungen von Perl ist die Objektorientierung zu nennen. Perl verfügt über die meisten Merkmale objektorientierter Sprachen. Somit erlaubt es die Entwicklung umfangreicher objektorientierter Frameworks, wozu auch SOAP::Lite gerechnet werden kann. Die zweite wichtige Neuerung (obwohl auch schon einige Jahre alt) ist die Unterstützung von Unicode. Damit wurde die Verarbeitung von XML möglich. Einzigartig ist das CPAN, das Comprehensive Perl Archive Network, welches nicht nur eine zentrale Sammlung von Perl-Modulen darstellt, sondern darüber hinaus noch ein einheitliches Verfahren zur Installation von Perl-Modulen definiert. Der Begriff Modul steht in der Perl-Welt sowohl für eine einzelne Datei (die eine oder mehrere Klassen enthalten kann) als auch für ganze Klassenbibliotheken. Zurück zu SOAP::Lite. Zu dessen Features gehören die Unterstützung von SOAP 1.1 und SOAP 1.2, verschiedenen Transportprotokollen (FTP, HTTP, IO, Jabber, SMTP, POP3, TCP und MQSeries) und neben SOAP auch XML-RPC als Protokoll. Auf der zugehörigen Website [2] findet man eine Auflistung aller Merkmale. Für Windows existieren verschiedene .dll-Dateien und eine Reihe von Beispielen für COM, .NET, VB, C# usw. Von der Homepage oder vom CPAN [3] kann die Software heruntergeladen werden. Die Installation unter Unix erfolgt dann nach dem CPAN-Strickmuster: perl Makefile.PLoder noch einfacher: Download und Installation in einem Rutsch mit Hilfe des CPAN-Moduls: perl -MCPAN -e shellVoraussetzung neben einem installierten Perl (zu bekommen unter [7] oder [8]) sind die Module XML::Parser, MIME::Base64 und URI, welche nach dem gleichen Schema installiert werden können. Eine Reihe weiterer Module sind je nach verwendetem Transportprotokoll notwendig, diese werden bei der Installation abgefragt und mit installiert. Die Dokumentation zu SOAP::Lite umfasst neben einem Quickstart Guide ein Cookbook und die Man Pages [2]. Zum Umfang der Distribution gehören auch eine Menge Beispielprogramme für Client- und Serverimplementierungen, die als Ausgangsbasis für eigene Anwendungen verwendet werden können. Die folgenden Beispiele beschränken sich auf HTTP als Transportprotokoll. Beginnen wir mit einem einfachen Client aus den Beispielprogrammen (client.pl). Die Programme sind in der Distribution enthalten oder können von guide.soaplite.com heruntergeladen werden Die Methode uri enthält den Namespace des Services, die Methode proxy die Adresse. In diesem Fall wird mit hibye.cgi ein CGI-Script aufgerufen: #!perl -wServerseitig unterstützt SOAP::Lite mehrere Varianten. Einmal als Standalone-Server, zum anderen die Integration in Apache über CGI, FastCGI oder mod_perl. Mit mod_perl wird ein Perl-Interpreter in Apache integriert, was eine wesentliche Performancesteigerung im Vergleich zu CGI zur Folge hat. Unser Client verwendet in seiner Adresse das CGI-Script hibye.cgi, also schauen wir uns zunächst die Implementierung als CGI-Script an (siehe Listing 1). Listing 1 1 #!perl -wIn Zeile 1 wird der Pfad des Interpreters genannt, je nach lokaler Perl-Installation ist dieser anzupassen. Zeile 2 lädt das Modul SOAP::Transport::HTTP, dies entspricht dem Import in Java. Darin wird eine Klasse mit dem Namen SOAP::Transport::HTTP::CGI definiert, in Zeile 5 wird festgelegt, welche Perl-Module als Web Service verwendet werden können. SOAP::Lite ermöglicht so völlig transparent, alle vorhandenen Module im Suchpfad von Perl als Web Service zu verwenden. Die Zeilen 8-14 definieren in einem eigenen Namensraum (Demo) die zwei Funktionen hi und bye. Das war es dann schon. Das Starten des Client liefert das Ergebnis: hello, world. Die hier gewählte Syntax weicht von der üblichen Form ab. Statt mit einem Konstruktoraufruf ein Objekt zu erzeugen und dann nacheinander dessen Methoden aufzurufen, können hier jede Methode der Klasse aufgerufen und weitere Methodenaufrufe aneinandergehängt werden (mit dem -> Operator). Returnwert ist immer das mit der ersten Methode erzeugte Objekt. Für Perl-Liebhaber bietet der Source von SOAP::Lite einige Beispiele zum Thema Codegenerierung. Um die Performance zu verbessern, werden wir als nächstes den Server nicht als CGI-Programm ausführen, sondern vom Apache selbst mit Hilfe des Perl-Interpreters aus mod_perl. Dies vermeidet das Starten eines neuen Prozesses und das Kompilieren des Programms bei jedem Request. Voraussetzung hierfür ist, dass Apache mit mod_perl kompiliert wurde. Unter perl.apache.org findet man die notwendige Software und die Dokumentation zur Installation. Viele Linux-Distributionen enthalten bereits einen entsprechenden Apache. Zur Installation unseres Web Services sind dann vier Schritte notwendig: Zuerst muss man einen Apache-Handler schreiben. Das ist nicht besonders schwierig, wie der folgende Quellcode zeigt: 1 package My::SOAP::Apache;Zeile 1 definiert den Namen des Moduls, die Datei muss dann unter My/SOAP/Apache.pm im Suchbaum von Perl gespeichert werden. Zeile 2 importiert die SOAP-Klassen, Zeile 4 erzeugt ein Server-Objekt und Zeile 7 definiert eine Funktion handler, welche vom Apache beim Eintreffen eines Request aufgerufen wird. Hier wird die Verarbeitung gleich an das Serverobjekt zur weiteren Verarbeitung weitergereicht. Wichtig ist die Zeile 5, die festlegt, welche Module für Web Services freigegeben sind. Hier kann eine Liste von Modulnamen stehen und es können einzelne Funktionen eines Moduls angegeben werden, zum Beispiel: <i>dispatch_to('Demo', 'My::SOAP::PLZ','My::SOAP::XY::func1')</i>
Hier sind alle Funktionen der Module Demo und My::SOAP::PLZ aufrufbar, während aus dem Modul My::SOAP::XY nur die Funktion func1 erreichbar ist.Schritt 2 ist die Konfiguration von Apache, hierzu muss die httpd.conf-Datei noch angepasst werden: <Location /soap>Damit wird festgelegt, dass (bei diesem Host, hier angenommen localhost), alle Requests in den Ordner /soap von dem Modul My::SOAP::Apache gehandelt werden. Schritt 3 besteht darin, das in Listing 1 enthaltene Package-Demo (ab Zeile 8, mit einer neuen Zeile am Ende, welche nur 1; enthält) als eigenes Modul Demo.pm im Perl-Suchbaum zu speichern. Zuletzt der vierte Schritt, die Anpassung des Clients aus dem ersten Beispiel. Die einzige Änderung betrifft die Adresse des Service, welcher jetzt unter der Adresse /soap zu erreichen ist: #!perl -wIn der Dokumentation und der Distribution finden sich noch eine Menge weiterer Beispiele mit verschiedenen Serverkonfigurationen. Hier soll noch ein Beispiel folgen, bei welchem ein Objekt übergeben wird und im Client völlig transparent aufgerufen werden kann. Möglich macht dies die AUTOLOAD-Funktion von Perl, mit welcher alle nicht auflösbaren Funktionsaufrufe abgefangen werden können. Dies macht sich SOAP::Lite zu Nutze und leitet diese Aufrufe weiter: 1 #!perl -wIn Zeile 3 wird mit der Anweisung +autodispatch diese Funktionalität eingeschaltet. Die Angaben zu uri und Proxy müssen dann als Hash (mit => und durch Komma getrennt) übergeben werden. In Zeile 7 wird dann ein Objekt der Klasse Temperatures erzeugt und in Zeile 8 dessen Methode as_fahrenheit aufgerufen. Hier ist kein Unterschied mehr zu einer normalen (lokalen) Syntax vorhanden. Die zugehörigen Serverlistings sind auf der soaplite-Website zu finden. Serialisierung, Typen und Namen Perl ist eine typenlose Sprache, daher gestaltet sich für Perl bei einfachen Datentypen die Serialisierung/Deserialisierung recht einfach. Befindet sich der Serialisierer im autotype-Modus, wandelt er die Parameter nach sinnvollen Regeln um. Eine Variable mit dem Wert abc bekommt den Typ string, eine Variable mit dem Wert 123 den Typ int, ein Hash wird in den Typ SOAPStruct umgewandelt usw. Das Autotyping kann ganz abgeschaltet werden oder man kann zu jeder Variablen den zugehörigen Typ mit angegeben. Dazu wird ein Objekt vom Typ SOAP::Data erzeugt und übergeben. Soll eine Variable mit einem Wert 123 als String übergeben werden muss statt $soap->function(123)geschrieben werden. Erwartet der Server benamte Variablen, wird der Name mit $soap->function (SOAP::Data->type(string=>123) ->name('myvar') )
angegeben.Serialisierer und Deserialisierer können durch eigene Klassen überschrieben werden. Dazu muss nur eine Unterklasse von deserializer/serializer entwickelt werden und bei der Erzeugung des Server-Objekts (bzw. des Clients, wenn dort ein eigener Serializer verwendet wird) angegeben werden: use SOAP::Transport::HTTP;MyDeserializer ist der Name der Klasse. Eine mögliche Anwendung ist z.B. das Hinzufügen eines Prefix bei Methodenaufrufen. Interoperabilität Die Dokumentation beschreibt eine Reihe von Clients für den Zugriff auf vorhandene Services, welche mit anderen Toolkits erstellt wurden. Am Beispiel eines .NET-Services sollen die notwendigen Anpassungen gezeigt werden. Services unter .NET erwarten zum einen benamte Parameter. Wie diese erzeugt werden, wurde schon beschrieben. Weiterhin verlangt .NET das Header-Feld SOAPAction in der Form service namespace, gefolgt von einem Slash, gefolgt vom Methodennamen. SOAP::Lite trennt Namespace und Methodenname jedoch durch ein #. Die notwendige Anpassung ist recht einfach (siehe Listing 2). Der Methode on_action wird ein Perl-Codeblock übergeben, in welchem die notwendigen Anpassungen durchgeführt werden. Mit der Anweisung sub {...} wird eine anonyme Subroutine erzeugt, welche mit der Funktion sprintf die übergebenen Parameter formatiert. Andere Server verlangen hier gegebenenfalls andere Formate. Dies ist ein schönes Beispiel für die Anpassungsfähigkeit von SOAP::Lite durch Eigenschaften der Sprache Perl. Mehr Informationen zum Thema Interoperabilität findet sich unter [5], Ergebnisse zu SOAP::Lite unter [6]. Listing 2 use SOAP::Lite;WSDL SOAP::Lite unterstützt auch WSDL. Um einen Service zu verwenden, genügt dann die Angabe der URL: use SOAP::LiteAlternativ kann die wsdl-Datei auch mit service => 'file:/your/local/path/StockQuoteService.wsdl' angegeben werden, wenn diese auf dem lokalen Filesystem liegt. In der Dokumentation wird darauf hingewiesen, dass komplexe Datentypen noch nicht funktionieren. Mit dem mitgelieferten Programm stubmaker.pl können Stubs erzeugt werden. Damit wird nichts anderes als ein Perl-Modul mit dem entsprechenden Namen erzeugt, welches dann wie andere Module mit use verwendet werden kann. Der Aufruf von perl stubmaker.pl http://www.xmethods.net/sd/StockQuoteService.wsdlerzeugt die Datei StockQuoteServic.pm. Damit kann der Web Service auf der Kommandozeile mit perl "-MStockQuoteService qw(:all)" -le "print getQuote('MSFT')"aufgerufen werden. Fehlerbehandlung Fehler bei SOAP-Requests können sowohl beim Transport als auch in der Anwendung selbst liegen. SOAP::Lite bietet hier mehrere Varianten der Fehlerbehandlung. Standardmäßig beendet sich ein Client bei einem Transportfehler mit der Fehlermeldung und ignoriert Anwendungsfehler. Um einen solchen festzustellen, muss daher die fault)=-Methode des Result-Objekts verwendet werden: ...Hier wird geprüft, ob ein Fehler vorliegt und, wenn ja, der Fehlercode und der Fehlertext ausgegeben. Um beide Arten von Fehlern abzufangen, kann ein Handler eingerichtet werden. Dazu wird der Methode on_fault eine anonyme Subroutine als Parameter übergeben. Diese Funktion wird dann bei einem Fehler aufgerufen. Bei einem Transportfehler ist der Fehler über das Client-Objekt ($soap) zu ermitteln, bei einem Anwendungsfehler über das Ergebnisobjekt. Daher prüft die Funktion mit ref $res, ob es sich bei dem zweiten Parameter um ein Objekt handelt (genauer, ob es sich um eine Referenz handelt, da in Perl Objekte als Datentyp eine Referenz darstellen). Der Aufruf von die beendet dann das Programm mit einer Fehlermeldung, aber hier kann auch beliebiger anderer Code ausgeführt werden: my $soap = <i>SOAP::Lite</i>Auf der Serverseite können sowohl der Fehlercode als auch der Fehlertext (faultstring) gesetzt werden. Weitere Angaben können in einer Variablen faultdetail abgelegt werden. Im einfachsten Fall verwendet der Server nur die Perl-Funktion die mit einer Fehlermeldung. Der Client kann diesen Text dann aus der Variablen faultstring auslesen (my_method im folgenden Quellcode). Den Zugriff auf alle Fehlervariablen erhält der Server mit der Klasse SOAP::Fault. Hier können alle Angaben vorgenommen werden (die_with_fault). In dem Feld faultdetail wird hier ein Objekt zurückgegeben: sub my_method {
FazitSOAP::Lite ist ein recht umfangreiches Toolkit zur Entwicklung von Clients und Servern für Web Services. Die Verwendung leistungsfähiger Module aus dem CPAN wie HTTP::Cookie oder LWP::UserAgent sowie die modulare Architektur ergeben zusammen mit Eigenschaften von Perl wie anonyme Subroutinen ein sehr flexibles und leistungsfähiges System. Die Dokumentation beschreibt eine Reihe weiterer Features von SOAP::Lite wie Zugriff über SSL, Authentifizierung, Cookies usw. Im Cookbook werden weitere Anwendungsfälle beschrieben, wie das Einfügen eines eigenen Header-Feldes, Zugriff auf den Envelope und natürlich auch die Verwendung von XML-RPC statt SOAP. Die aktuelle Versionsnummer 0.58 sollte niemanden vor dem Einsatz zurückschrecken: Der Code ist sehr stabil und Perl-Autoren sind generell sehr zurückhaltend mit der Vergabe einer 1.* Version. Der Autor ist freiberuflicher Softwareentwickler und arbeitet am liebsten mit Perl. Zu erreichen ist er unter rolf.schaufelberger@web.de. Links und Literatur
|
||
|