![]() |
Comelio GmbH
|
Comelio-Blog > MS SQL Server > Programmierung mit T-SQL Programmierung
Webservice-ProgrammierungNach den vielen verschiedenen allgemeinen Informationen und Darstellungen, wie die Technologie in der Theorie gedacht und im MS SQL Server umgesetzt wird, folgen nun Beispiele, in denen eine Reihe von Webservices auf Basis von Prozeduren und Funktionen eingerichtet werden. Eine Prozedur als Webservice anbietenZunächst benötigt man eine Prozedur, die sich als Webservice eignet. Sie zeichnet sich dabei weniger durch ihre tatsächliche Funktionsweise aus, sondern durch die Art und Weise, wie Eingabe und Ausgabeparameter verarbeitet und erzeugt werden. In diesem ersten Beispiel handelt es sich um eine Prozedur namens GetProductInfo, die auf Basis einer eingegebenen Produktnummer Informationen zu einem Produkt ermittelt. Um den Quelltext nicht unnötig zu verlängern, ist die eigentliche Funktionalität dieser Prozedur (wie auch bei allen anderen Beispielen) sehr kurz gehalten. Theoretisch kann natürlich jeder beliebige T-SQL-Quelltext geschrieben werden, der für die Lösung einer Aufgabenstellung notwendig ist. Als besonderes Merkmal führt diese Prozedur nicht einfach nur eine SQL-Abfrage auf Basis der übergebenen Produktnummer aus, sondern erstellt eine XML-Antwort mit Hilfe der FOR XML-Klausel. Es ist – wie in einem späteren Beispiel gezeigt wird – durchaus möglich, eine relationale Ergebnismenge zurückzuliefern, die dann automatisch in eine XML-Darstellung überführt wird. Ihr Aufbau ist allerdings vorgelegt und wird automatisch auf Basis der Spaltennamen erzeugt. In diesem Fall erstellt man ein eigenes Format.
Mit Hilfe der der Anweisung CREATE ENDPOINT lässt sich nun diese Prozedur als Endpunkt und damit auch als Webservice anlagen. Sie soll unmittelbar nach Erstellung auch abrufbar sein, sodass STATE = STARTED angegeben wird. Der Pfad, unter dem man sie aufrufen kann, lautet /sql, die Sicherung gelingt über die integrierte Authentifizierung (ein späteres Beispiel zeigt eine andere Sicherheitstechnik), und über localhost soll der Endpunkt unter dem angegeben Pfad gefunden werden. Die Prozedur wird als SOAP-Webdienst angeboten, gehört zur AW-Datenbank, liefert die WSDL-Datei automatisch zurück (WSDL = DEFAULT) und liegt im Namensraum http://Adventure-Works/Products. Batch-Anweisungen sind unter diesem Webservice nicht zulässig (BATCHES = DISABLED).
Während der vorherige Quelltext nur den Endpunkt als solchen einrichtet, benötigt man noch in der master-Datenbank verschiedene weitere Einstellungen, die über Verwaltungsprozeduren für Webservices eingerichtet werden können.
Die Prozedur sp_reserve_http_namespace legt eine explizite Namensraum-Reservierung für einen Endpunkt fest, wobei keine Administrationsrechte auf dem Server notwendig sind, sondern lediglich die Prozedur erlaubt sein muss. Dabei kommt für den Namensraum die Form <scheme>://<hostpart>[:<port>]/ <RelativeURI> zum Einsatz. Für scheme kann man die beiden Werte http oder https verwenden, während hostpart durch einen gegebenen Hostnamen oder einen Platzhalter wie ein Pluszeichen (Reservierung gilt für alle Hostnamen in diesem Schema und den Computer) oder ein Sternchen (Reservierung gilt für die mit dem Pluszeichen angegebenen Hostnamen und das Schema, sofern sie nicht anderweitig durch die gleiche Prozedur, aktive Endpunkte oder Dritt-Anwendungen reserviert sind) ersetzt werden kann. Mit der Prozedur sp_delete_http_namespace_reservation kann eine solche Reservierung wieder gelöscht werden, wobei die gleiche Notation für den Namensraum gilt. Auch wenn der Quelltext korrekt läuft und alle einzelnen Anweisungen bestätigt werden, ist dies noch keine Gewissheit oder kein Beweis, dass der Webservice verfügbar ist. Dazu lassen sich die beiden URLs http://localhost/sql?wsdl und http://localhost/sql?wsdlsimple verwenden, um die beiden verschiedenen WSDL-Dateien abzurufen. Es ist in .NET und auch in anderen Sprachen nicht notwendig, tatsächlich eine SOAP-Nachricht zu erstellen, aber die Funktionsweise eines Webdienstes kann über eine SOAP-Nachricht auf einfache Weise überprüft werden. Man kann die Parameter leicht variieren, muss keinen Klienten erstellen, sondern kann einen fertigen Klienten verwenden, der nur SOAP-Anfragen an den Endpunkt sendet, und die Antwort wieder anzeigen. Da im Normalfall typisiertes XML zum Einsatz kommt, kann man leicht aus der XML Schema-Datei eine entsprechende Frage entwickeln, da es ja im Wesentlichen nur auf das versendete XML ankommt. Die Struktur der Nachrichten ist darüber hinaus nicht nur für das Visual Studio lesbar, sondern für den Programmierer ebenfalls, weil die erwarteten Anfragen und Antworten schließlich im WSDL-Dokument verzeichnet sind. In der Anfrage ruft man im Body-Element den Webservice über den angegebenen Namen auf, der als direktes Kind-Element verwendet wird. Dabei verwendet man den zuvor bei der Anmeldung des Dienstes angegebenen (spielerischen) Namensraum. Der Parametername der Prozedur dient hier wiederum als Vorlage für das Kind-Element, das den Parameterwert enthält.
In der Ergebnismenge gibt es zwei Bereiche, die man in einem Element GetPro-ductInfoResponse/GetProductInfoResult findet, welcher wiederum automatisch aus dem Prozedur-/Webservicenamen gebildet wird. Im ersten Bereich befindet sich das SqlXml-Element, das wiederum innerhalb von einem SqlXml-Element die von der FOR XML-Abfrage erzeugte XML-Nachricht enthält. Das Element SqlRowCount liegt auf der gleichen Ebene wie das zweite SqlXml, welche Meta-Informationen über die Ergebnismenge enthält. In diesem Fall erfährt man nur, dass genau eine Zeile abgerufen wurde. Schließlich folgt noch als Geschwister-Element vom ersten SqlXml-Element das Element SqlResultCode, welches den Fehlerstatus enthält.
Eine Funktion und eine Prozedur als Webservice anbietenEin Webservice besteht in einem realistischen Szenario durchaus nicht nur aus einer einzigen Operation. Wenigstens verschiedene überladene Varianten, d.h. Operationen mit gleicher Funktionalität und unterschiedlichen Parametern, findet man sehr häufig. Bei einem komplexen Dienst folgen dagegen verschiedene Operationen, sodass man sich bei der AdventureWorks-Datenbank solche Operationen wie Produktsuche, Bestellung, Statusanfrage in einem einzigen Webservice denken könnte, die zu unterschiedlichen Zeiten und/oder im Rahmen einer Transaktion in einer bestimmten sachlogischen Reichenfolge aufgerufen werden. Dadurch erhält der Webservice auch insgesamt mehr den Charakter einer Programmierschnittstelle, die einen größeren Verantwortungsbereich verwaltet als nur Informationen auszugeben oder für eine interne Verarbeitung einmalig anzunehmen. Um zu zeigen, wie man eine Liste von Prozeduren/Funktionen an einem Endpunkt anbietet und wie man eine Funktion anstelle einer Prozedur verwendet, folgt nun die Funktion GetProductsPerSubcategory. Sie liefert die Anzahl der Produkte anhand einer Unterkategorienummer zurück. Unabhängig davon, dass hier eine Funktion verwendet wird, ist der zu erwartende Rückgabewert in diesem Fall auch gerade nicht vom Typ xml, sondern stattdessen vom skalaren Typ int. Man kann sich an dieser Stelle also auch vorstellen, dass man eine ganz gewöhnliche Funktion/Prozedur als Webservice anbietet und den MS SQL Server entscheiden lässt, wie dann die entsprechenden SOAP-Nachrichten aussehen sollen.
In diesem Fall gibt der nachfolgende Quelltext noch einmal an, dass der bestehende Endpunkt zunächst gelöscht werden muss, bevor man Änderungen vornehmen kann. In den anderen Skripten, die teilweise immer wieder die gleichen Endpunkte überschreiben, sind diese Schritte dann ebenfalls auszuführen und befinden sich auch in den dazugehörigen Skripten. Sie werden allerdings nicht jedes Mal erneut abgedruckt. Wenn man gleichzeitig verschiedene Webservices testen möchte, die in diesem Kapitel erstellt werden, dann sollte man am besten die Namen und natürlich die Pfade der Endpunkte ändern. Als Neuerung ist in diesem Quelltext zu sehen, wie gleichzeitig mehrere Operationen in einem Webservices angeboten werden. Dies geschieht ganz einfach durch eine Auflistung der Prozedur und Funktion, die zuvor erstellt wurden. Die beiden WSDL-Dokumente, die diesen Webservice beschreiben, befinden sich in den Dateien 532_01.wsdl und 532_01_simple.wsdl. Es interessieren in beiden möglichen WSDL-Dokumenten weniger die Datentypangaben, die ja in jedem WSDL-Dokument gleich sind, sondern vielmehr die Nachrichtenstrukturen. In diesem Fall fällt auf, dass bei der Prozedur eine XML-Datei zurückgegeben wird, deren Struktur allerdings nicht spezifiziert ist, während als Rückgabewert der Funktion nur ein Element zum Einsatz kommt.
Klienten in .NETAuch wenn es viele verschiedene Möglichkeiten gibt, Klienten für die erstellten Webservices in .NET zu erstellen, soll doch an dieser Stelle ein kurzer Exkurs eingeflochten werden, der zeigt, dass die eingerichteten Dienste tatsächlich im Visual Studio abrufbar sind. Dabei ist in der einfachen Version, bei der ein Webdienst einfach nur einen atomaren Wert und gerade keine XML-Struktur zurückliefert, auf den Assistenten voller Verlass.
Die Miniaturanwendung fragt den Benutzer in der Konsole nach der Nummer einer Unterkategorienummer, um diesen Wert der Webserviceoperation GetProductsPerSsubcategory zu übergeben, welche dann die entsprechende Anzahl an Produkten abruft und wieder ausgibt. Neben diesen Aktionen innerhalb der Konsole, welche nicht weiter spektakulär sind, ist es interessant, wie einfach durch das WSDL-Dokument die Operation eines Webservices an einem Proxy (Stellvertreter)-Objekt aufgerufen werden kann. Der Webservice wird unter dem zuvor gespeicherten Namen als Klasse innerhalb des Projekts verfügbar gemacht, sodass ein Objekt seines Typs angelegt werden kann, von dem die verschiedenen Webservice-Operationen als Methoden abrufbar sind.
Der Klient lässt sich aus dem Ordner EINFACHE WS 5.1\CLIENT1\ CLIENT1\CLIENT1\BIN\DEBUG heraus unter Client1.exe öffnen und liefert bspw. für die Unterkategorienummer 2 die Anzahl von 43 Produkten.
Seminare
|