M2M mit SOAP

Bis jetzt beschränkte sich dieses Kapitel darauf, XML-Dateien, welche ein maschinenlesbares Format darstellen, einzulesen und zu modifizieren. Es liegt nun nahe, diese Dateien nicht nur lokal im Dateisystem abzulegen, sondern sie bei Bedarf von einem entfernten Server anzufragen, der diese dann anhand von übergebenen Parametern generiert und verschickt. Genau dies ist die Grundidee für Services, die an den unterschiedlichsten Stellen im Internet angeboten werden und von anderen Systemen – meist sind dies Webseiten – in Anspruch genommen werden.

Zur Hochzeiten von XML wurde hierfür eine standardisierte Schnittstelle geschaffen, die sich SOAP-Schnittstelle nennt, wobei SOAP für Simple Object Access Protocol steht. Diese Schnittstelle spezifiziert, wie XML-Fragmente in sogenannte Envelopes eingebettet, die wiederum XML-Konstrukte darstellen über das Netz in verschiedenen Diensten – einer davon ist HTTP – transportiert werden können. Wird von Client-Seite eine Serviceanfrage abgeschickt, so nimmt diese der Server entgegen und führt intern einen Funktionsaufruf aus. In dieser aufgerufenen Funktion kann der Programmierer des Servers nun die notwendigen Aktionen durchführen und die Daten zusammenstellen, die als Antwort wieder zurückgeliefert werden.

SOAP geht noch weiter und stellt eine Spezifikation bereit, nach welcher die Dienste eines Servers innerhalb eines XML-Dokumentes maschinenlesbar beschrieben werden. Dieses Dokument wird WSDL genannt. Hier werden alle Kommandos eines Services mit den Übergabeparametern und Rückgabeparametern aufgelistet, so dass ein Dienstnutzer allein anhand dieser Datei alle angebotenen Services vollständig nutzen kann. Die Idee wurde dann in der Hochzeit des XML-Hypes noch weiter fortgeführt. Es sollten Verzeichnisse entstehen, in denen Server, die eine solche WSDL anbieten gelistet werden und somit ein großer Katalog an nutzbaren Datenquellen entstehen würde. So würde neben dem Internet für Menschen ein Internet für Maschinen entstehen.

Am Ende konnte sich jedoch SOAP nicht durchsetzen. Dies hat wohl den Grund, dass Firmen ungerne ihre Daten über eine Schnittstelle nach außen an die gesamte Welt in maschinenlesbarer Form weitergeben. Dies ist nur für einen kleinen Teil an Datenquellen interessant. Andere Datenquellen können genutzt werden, wenn dafür bezahlt wird, da die Betreiber dieser Server selbst viel Zeit und Mühe dorthinein investieren, diese Daten zu erstellen und aktuell zu halten. Somit stirbt die Idee eines Verzeichnisses von Datenquellen, aus denen sich jeder bedienen kann und komplizierte Lizenzmechanismen müssen eingefügt werden. Auch die WSDL ist zwar für Maschinen gut lesbar, aber für Menschen doch wieder zu komplex, als dass sie auf Anhieb verstanden wird. Zu guter letzt stellte man fest, dass die Idee, das XML nochmals einzupacken, performanceaufwändig ist. Da der Ein- und Auspackvorgang für eine große Anzahl von Service-Anfragen genutzt werden muss, ging in den Systemen wertvolle Rechenzeit verloren und man sah sich nach Alternativen um. Diese Alternative ist in den REST-Schnittstellen dann gefunden worden, weshalb es zugunsten der REST-Schnittstellen heutzutage kaum mehr SOAP-Schnittstellen gibt.

Trotzdem wird hier kurz auf die SOAP-Implementierung von PHP eingegangen, da PHP eine Implementierung mitbringt, die äußerst einfach zu nutzen ist. Dabei wird auf die aufwändige Formulierung einer WSDL verzichtet.

Es wird mit dem Aufbau des Serverteils begonnen, welchen unter server.php abgelegt wird:

Zunächst befindet sich im Quellcode die selbst definierte Klasse SOAPAPIWrapper, die in der vorletzten Zeile mit setClass() im SOAP-Server gesetzt wird. Alle Funktionen in unserer Klasse können nun von einem externen SOAP-Client aufgerufen werden und deren Ergebnisse werden über die Netzschnittstelle an diesen zurückgesandt. Alternativ wäre es möglich, dem SOAP-Server auch mit der Funktion addFunction() einzelne Funktionen zu übergeben. Damit es möglich ist, unseren Server ohne eine WSDL zu betreiben, muss ein Array mit Optionen übergeben werden, in welchem die URI festgelegt wird. In diesem Fall zeigt diese einfach auf http://www.fit4php.net. Wichtig ist, dass diese URI keinesfalls als Webadresse zu sehen ist, sondern nur ein Matching möglich sein soll. Daneben sind noch weitere Optionen möglich, wie etwa, welche SOAP-Version genutzt werden soll, ob Kompression genutzt werden soll, welches Encoding genutzt wird, wie Authentifizierung betrieben wird und weitere, die aber hier ausgespart werden sollen. Weiter wird der SoapServer erstellt und zwar mit NULL als WSDL. In der letzten Zeile unseres Listings wird der SOAP-Request behandelt. Unsere Datei server.php wird nun auf dem entfernten Server bereitgestellt. Ein einkommender Request ruft diese Datei auf, das PHP-Skript wird ausgeführt und die SOAP-Anfrage entsprechend behandelt.

Der Client-Teil wird beispielsweise unter client.php abgelegt und sieht wie folgt aus:

Zunächst ist im Code ein Array an Optionen zu finden, in welchem wiederum die URI definiert wird. Zusätzlich wird ein location-Attribut übergeben. Dieses teilt dem Client mit, wo unser SOAP-Service zu finden ist. Es ist der Ort, an welchem die server.php deployt wurde. Der SoapClient wird initialisiert. Wieder wird NULL übergeben, um anzuzeigen, dass es keine WSDL gibt. Dann wird der Client angewiesen, die Funktion getTime() auf dem Server remote auszuführen. Der Client sorgt dafür, dass die passende SOAP-Anfrage über die Schnittstelle geschickt wird. Der Server antwortet. Die Antwort wird dem aufrufenden Programm zur Anzeige mit echo zurückgegeben.

Bei der Nutzung von SOAP kann es zu Fehlern kommen und zwar auf zwei Seiten: einmal auf der Server-Seite und einmal auf der Client-Seite. Über die Funktion use_soap_error_handler() ist es möglich, den Server anzuweisen, Fehler als SOAP-Nachrichten an den Client zu senden. Dies ist jedoch standardmäßig ausgeschaltet. Mit Hilfe von is_soap_fault($result) kann auf der Client-Seite geprüft werden, ob ein SOAP-Fehler vorliegt. Ist dies der Fall beinhaltet das $result-Objekt sowohl faultcode wie auch faultstring. Alternativ kann der Fehler auch über eine Exception SOAPFault behandelt werden. Hierfür muss aber über die Optionen der Client mit "exceptions" => true angewiesen werden, dass er Exceptions werfen soll.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert