Freitag, 16. Januar 2009

WSDL: Eine Nachbetrachtung

Alle Jahre wieder gibt es neue Blogeinträge so wie hier dieser. Fast vier Wochen ist es her, dass ich vom Almighty Webservice Client berichtet habe, und jetzt ist es Zeit für neue Meldungen.

Während kurz vor der Deadline noch alles wunderbar funktioniert hat, meldete sich der Client in den frühen Morgenstunden und am Vormittag darauf mit einem Error. Grund dafür war, dass einige Kollegen ihre fehlerhaften Webservices offenbar gelöscht haben, sodass SoapClient nur einen HTTP 404 Fehler anstatt einer brauchbaren Description XML vorfinden konnte. Da diese Möglichkeit im Client schlicht und einfach nicht berücksichtigt wurde, verwundert das Verhalten auch nicht weiter. Inzwischen ist die Liste der Webservices zwar geschrumpft, dafür aber auch wieder fehlerlos.

Gegen Ende des letzten Jahres hatte ich dann noch die Idee, man könnte doch auch einen generischen Server erstellen. Das klingt zuallererst einmal total verrückt, und ich distanziere mich auch hohoffiziell von jeglicher gedanklicher Inbeziehungstellung mit Sekt oder dergleichem. Technisch ist das aber durchaus machbar.

Wie wir inzwischen wissen sollten, erfolgt die Zuordnung zu einer Klasse zB mit $server->setClass("MissWorld"), die Operationen anhand ihres Namens in Methodenaufrufe übersetzt. Wenn die Operation also "schaffeWeltfrieden" heißt dann wird vom SoapServer Proxy die $missWorldInstance->schaffeWeltfrieden(); Implementierung aufgerufen.

Aber... da müsste man doch die Klasse mit allen je möglichen Operationen/Methoden ausstatten, und das geht ja gar nicht !? Klar, das müsste man, und das kann man mit Hilfe einer magischen Methode (ja, die heißt wirklich auch offiziell so!) machen, nämlich __call():

"__call() is triggered when invoking inaccessible methods in an object context."
http://us.php.net/manual/en/language.oop5.magic.php
Mit Hilfe der aus dem Almighty Client bekannten Parserei schauen wir dann nach, wie der retournierte Typ aussehen muss (primitiver Wert bzw. ComplexType). Die Generierung der Daten erfolgt dann entweder randomisiert oder durch Wiederverwendung der Eingabedaten.

Die Server Klasse könnte dann ungefähr folgendermaßen aussehen, wobei hier davon ausgegangen wird, dass die Argumente primitive Typen und keine Arrays sind, und dass der Rückgabewert ein nicht verschachtelter ComplexType mit primitiven Attributen ist:

class AlmightyServer
{
public function
__call($name, $arguments)
{
$object = WsdlParser::getReturnObjectFor($name);
foreach(get_object_vars($object) as $key=>$value)
{
$object->$key = $arguments[ rand( 0,count($arguments) ) ];
}
return $object;
}
}


Daraus ist aber dann nichts geworden, unter anderem weil das Teamprojekt gerufen hat. Aber davon erst am Wochenende mehr.

Keine Kommentare: