Veröffentlicht: 19. Aug 2001 | Aktualisiert: 18. Jun 2004
Von Scott Seely
In dieser Kolumne betrachten wir, was zu beachten ist, wenn der Vertrag für Ihren Webdienst entworfen wird. Hoffentlich kommen Ihnen bei dem Gedanken "Webdienst" nicht mehr so profane Dinge wie das einfache Abrufen von Börsenkursen oder das Anzeigen der Temperatur an Ihrem Heimatort in den Sinn. Stattdessen sollten Sie Webdienste als Komponenten sehen, deren APIs mit "allen Wassern gewaschen sind". In dieser Kolumne begutachten wir den Entwurf der Schnittstelle des Webdienstes sowie alle evtl. nötigen Globalisierungsanforderungen.
.gif)
Links zu verwandten Themen |
Auf dieser Seite
Einführung
Definieren der Schnittstelle des Webdienstes
Globalisierung des Webdienstes
Schlussfolgerung
Einführung
Es ist schon eine Weile her, seit wir uns Ihnen in der At Your Service-Kolumne mitgeteilt haben. Weil wir solche langen Zeitabstände vermeiden möchten, setzen wir ab jetzt ein Team an das Projekt, bestehend aus Matt Powell und Scott Seely. Ich, Scott, darf zuerst schreiben. Mary Kirtland hat uns vor kurzem im Artikel Getting to Know Us (in Englisch) vorgestellt. Trotzdem möchten wir uns noch etwas näher vorstellen, jetzt, wo wir in regelmäßigen Abständen in diesem Forum vertreten sind.
Matt ist seit mehr als 10 Jahren bei Microsoft. Die meisten Jahre davon hat er in der Developer Support-Gruppe verbracht. Er besteht darauf, als Netzwerkprotokollspezialist bezeichnet zu werden, da er die Gelegenheit hatte, die verschiedensten Protokolle zu betreuen: von DLC über NetBIOS, Winsock, RPC, SNMP und WinInet bis hin zu ISAPI. Matt bevorzugt die MS-DOS-Eingabeaufforderung gegenüber dem Windows Explorer und kann in Sekundenbruchteilen EDLIN aufrufen, um eine Textdatei zu bearbeiten. In seiner Freizeit liebt Matt es, seine Familie - und das sind immerhin 9 Personen - zu den Spielen der Seattle Mariners mitzunehmen. Er sitzt in der ersten Reihe, direkt hinter Ichiro, schwenkt ein weißes Handtuch und versucht meistens, seine eigene Motivation an die Spieler weiterzugeben.
Wenn Sie die vergangenen Ausgaben dieser Kolumne gelesen haben, werden Sie evtl. bemerkt haben, dass eines unserer Teammitglieder, James Francisco, erwähnte, dass wir weit hinter dem Zeitplan bleiben, weil die Hälfte der Entwickler (ich) im Vaterschaftsurlaub weilt. Am 15. März habe ich meine Tochter kennen gelernt, Angeline. Vier Wochen haben ihre Mutter, ihr großer Bruder und ich die Zeit damit verbracht, unser neues Familienmitglied zu begrüßen. Ich habe die Zeit auch genutzt, um mein Buch über SOAP, SOAP: Cross Platform Web Service Development Using XML, für Prentice Hall fertig zu stellen. Ende Juli 2001 wird es in die Regale kommen. Neben dem Schreiben bin ich außerdem der Mann für alles Plattformübergreifende. Warum? Ich habe drei nicht von Microsoft stammende SOAP Toolkits verwendet: mein eigenes SimpleSOAP sowie Apache SOAP und SOAP::Lite.
Definieren der Schnittstelle des Webdienstes
Heutzutage teilen wir anderen mit, wie sie einen Webdienst erreichen und nutzen, indem wir eine WSDL-Datei verwenden (WSDL = Web Services Description Language). Als SOAP eingeführt wurde, kamen mehrere XML-basierte Sprachen zur Schnittstellenbeschreibung (IDLs, Interface Description Languages) auf. Alle diese IDLs kannten verschiedene Möglichkeiten, einen Dienst zu beschreiben, und enthielten Elemente, die spezifisch für die SOAP-Implementierung waren, an die sie gebunden wurden. Die Industrie erkannte schnell den Bedarf an standardisierten Sprachen, und WSDL wurde entwickelt. WSDL beschreibt die folgenden Elemente:
-
Die vom Webdienst erkannten Datentypen
-
Das Nachrichtenschema
-
Die vom Webdienst verwendete Austauschmethode (Anforderung/Antwort, Einwegübertragung, Multicast usw.)
-
Den Standort des Webdienstes
-
Fehlerinformationen
-
Headerinformationen
Eine komplette Beschreibung von WSDL würde den Rahmen dieses Artikels sprengen. Am Ende des Artikels finden Sie jedoch Links zu einigen exzellenten WSDL-Hintergrundinformationen. Jetzt möchte ich mich darauf konzentrieren, wie die oben genannten Elemente verwendet werden, um die Schnittstelle des Webdienstes zu definieren.
Beim Definieren der Schnittstelle sollten Sie zunächst die Datentypen festlegen. Stellen Sie immer sicher, dass Sie die Typen wieder XML Schema-Datentypen zuordnen können. Für Zeichenfolgen sollten Sie z.B. xsd:string verwenden. Wenn Sie komplexe Typen erstellen, sollten Sie diese evtl. in einen der vordefinierten XML Schema-Datentypen zerlegen. Sie könnten einen Kontakt z.B. nach E-Mail-Adresse und Rufnummer (geschäftlich) definieren. Der types-Abschnitt der WSDL-Datei sähe folgendermaßen aus:
<definitions xmlns:s="http://www.w3.org/2001/XMLSchema"
xmlns:s0="http://tempuri.org/"
targetNamespace="http://tempuri.org/"
xmlns="http://schemas.xmlsoap.org/wsdl/">
<types>
<s:schema attributeFormDefault="qualified"
elementFormDefault="qualified"
targetNamespace="http://tempuri.org/">
<s:element name="ContactInfo">
<s:complexType>
<s:sequence>
<s:element minOccurs="1" maxOccurs="1"
name="name" nillable="true"
type="s0:PersonName" />
<s:element minOccurs="1" maxOccurs="1"
name="emailAddress" nillable="true"
type="s0:EmailAddress" />
<s:element minOccurs="0" maxOccurs="unbounded"
name="phoneNumbers" nillable="true"
type="s0:PhoneNumber" />
</s:sequence>
</s:complexType>
</s:element>
<s:complexType name="PersonName">
<s:sequence>
<s:element minOccurs="1" maxOccurs="1" name="first"
nillable="false" type="s:string" />
<s:element minOccurs="1" maxOccurs="1"
name="middle" nillable="true"
type="s:string" />
<s:element minOccurs="1" maxOccurs="1" name="last"
nillable="false" type="s:string" />
</s:sequence>
</s:complexType>
<s:complexType name="PhoneNumber">
<s:sequence>
<s:element minOccurs="1" maxOccurs="1"
name="areaCode" nillable="false"
type="s:long" />
<s:element minOccurs="1" maxOccurs="1" name="prefix"
nillable="true" type="s:long" />
<s:element minOccurs="1" maxOccurs="1" name="suffix"
nillable="false" type="s:long" />
</s:sequence>
</s:complexType>
</s:schema>
</types>
...
</definitions>
Wie Sie sehen, reduzieren sich alle komplexen Typen plötzlich zu einem vorhandenen XML Schema-Datentyp. Indem Sie diese Einschränkung verwenden, erhöhen Sie die Wahrscheinlichkeit, dass andere SOAP-Implementierungen in der Lage sind, mit Ihrem Webdienst zu interagieren. Warum? Viele XML Schema-Implementierungen sind für viele verschiedene Plattformen verfügbar indem Sie sich an Standards halten und Erweiterungen Ihrer Lieblingsimplementierung vermeiden, erhöhen Sie die Nutzbarkeit Ihres Webdienstes.
Als Nächstes sollten Sie sich überlegen, wie Sie den Faktor "Funktionalität" des Webdienstes einsetzen. Beim Programmieren eines Webdienstes sollten Sie verwandte Vorgänge in einem einzigen Port zusammenfassen. Für den Favoritendienst haben wir den Entwurf in drei Dienste zerlegt:
-
Anmeldung: Authentifiziert Lizenznehmer(innen) und gewährt ihnen einen Schlüssel, den sie beim Zugriff auf den Dienst verwenden
-
Konto: Verwaltet die Erstellung von Endbenutzern und Favoritendaten
-
Bericht: Verwaltet alle Berichtsfunktionen
Indem Sie die Funktionalität in Blöcke verwandter Funktionen unterteilen, erleichtern Sie es Benutzern des Webdienstes, die benötigten Funktionen zu finden, wenn ein bestimmtes Feature eingesetzt wird. Die Programmierer wissen dann, dass die verwandten Funktionen an einem bestimmten Port zur Verfügung stehen, wodurch sie es wesentlich einfacher haben.
Die Implementierung dieser Ports befindet sich i.d.R. innerhalb eines Objekts. Intern können diese Objekte allgemeine Hilfsprogrammfunktionen gemeinsam nutzen. Extern sollten diese Objekte sich nicht auf den internen Status verlassen. Ich habe die Newsgroups beobachtet und gesehen, dass viele Leute dadurch frustriert wurden, dass sie versucht haben, Zeiger oder Verweise für SOAP-Objekte zu übergeben. Warum sind diese Leute frustriert? Weil sie etwas entwerfen, für das ein Zeigerverweis erforderlich ist, und dann schnell feststellen, dass SOAP dies nicht zulässt.
Wenn Sie sich in eine Sackgasse codiert haben, habe ich einen guten Workaround für Sie: in/out-Parameter. Egal ob ein Objekt ein in-, out- oder in/out-Parameter ist, es muss in der Lage sein, seinen Status in XML zu schreiben. Wenn Sie den Teil des benötigten Objekts angeben, analysieren Sie, welche Daten die Funktion wirklich benötigt, und fordern Sie diese Informationen an. Dies kann einen erheblichen Unterschied ausmachen, da die Übertragung der Daten im Netzwerk mehr Zeit in Anspruch nehmen kann als der gesamte Serialisierungsvorgang. Je kleiner die Nachricht, desto geringer ist die Zeit, die zum Übertragen der Nachricht an das Ziel erforderlich ist.
Sie sollten auch sicherstellen, dass Sie die Parameter überwachen, die hin und her gehen. Wenn Sie ein Tool verwenden, das die WSDL für Sie erstellt, z.B. die .NET Runtime oder das SOAP Toolkit v2-Tool WSDLGEN.EXE, wissen Sie u.U. nicht, dass Sie Bandbreite verschenken. Während Sie an der Lösung arbeiten, sollten Sie sich etwas Zeit nehmen, um die erzeugte WSDL zu untersuchen. Prüfen Sie, ob Sie an einigen Stellen die hin und her gehenden Nachrichten etwas kürzen können. Alle Parameter, die als ByRef-Parameter in einem Visual Basic COM-Objekt gesendet werden (und sie sind alle ByRef, wenn Sie nichts anderes angeben), sind in/out-Parameter. Wenn Sie das Objekt verwenden, vor der Rückgabe allerdings nicht ändern, senden Sie den Parameter stattdessen als ByVal zurück. Untersuchen Sie genauso die IDL-Dateien für Ihre C++-Objekte, und stellen Sie sicher, dass die Parameter entsprechend ausgezeichnet sind.
Ihr Webdienst verwendet i.d.R. Anforderung/Antwort - den herkömmlichen Remoteprozeduraufruf. Sie können eine Einwegübertragung festlegen, indem Sie das output-Element der operation weglassen.
Anforderung/Antwort:
<operation name='DeleteFavorite' parameterOrder='key Username FavID'>
<input message='wsdlns:Account.DeleteFavorite' />
<output message='wsdlns:Account.DeleteFavoriteResponse' />
</operation>
Einwegübertragung:
<operation name='DeleteFavorite' parameterOrder='key Username FavID'>
<input message='wsdlns:Account.DeleteFavorite' />
</operation>
In der einwegübertragenen Nachricht ist die Ausgabenachricht einfach weggelassen worden. Wenn Sie es für sinnvoll halten, die output message wegzulassen, tun Sie es. Das reduziert die Wartezeiten und kann den Dienst schneller erscheinen lassen, da der Client nicht auf eine Antwortmeldung warten muss.
Da WSDL eine IDL ist, stellt sich für den dem WSDL-Port zugrunde liegenden Code die einzige Anforderung, dass er alle SOAP-Anforderungen korrekt beantworten muss. Was bedeutet das für Sie? Stellen wir uns nun vor, dass wir in einer Clientanwendung arbeiten, die mit Servern kommuniziert, auf denen Bestellungen verarbeitet werden. Der eine Server verarbeitet Möbelbestellungen, ein zweiter Buchbestellungen, und ein dritter Server verarbeitet DVD-Bestellungen. Wobei wir annehmen, dass der einzige Unterschied zwischen diesen Systemen die Artikeldatenbank ist, können wir mit demselben Client auf diese verschiedenen Dienste zugreifen. Der einzige Unterschied sollte der Endpunkt des Dienstes sein. (Dies ist eines der Konzepte, auf denen UDDI beruht.) Die SOAP-Bindung von WSDL ermöglicht dies durch die Verwendung des soap:address-Elements.
<service name='Account' >
<port name='AccountSoapPort' binding='wsdlns:AccountSoapBinding' >
<soap:address location='http://coldrooster.com/ssf/account.asp' />
</port>
</service>
Viele WSDL-orientierte Toolkits ermöglichen Ihnen die Änderung des Endpunktes nach dem Einlesen der Datei. Wenn Sie den Standort der anderen Dienste kennen, die den Port implementieren, oder wenn Sie einen UDDI-Server zum Abruf ähnlicher Informationen verwenden, können Sie denselben Client verwenden, um mit verschiedenen Endpunkten zu kommunizieren.
Wenn Sie sich etwas Zeit für den Entwurf der SOAP-Schnittstelle nehmen, sollten Sie Ihren Webdienst von jedem Computer aus aufrufen können. Wenn mehrere Quellen den gleichen Dienst anbieten, ermöglicht es eine gemeinsame Schnittstelle einem einzelnen Client, auf die verschiedenen Webdienste zuzugreifen. Legen Sie beim Entwurf dieser Anwendungen mit Hilfe automatisierter WSDL-Generierungstools eine Pause ein, um sich die generierte WSDL anzusehen, und stellen Sie sicher, dass Sie nur das senden, was unbedingt erforderlich ist. Bei kurzen Operationen werden Sie feststellen, dass das Netzwerk der Engpass ist.
Globalisierung des Webdienstes
Sie müssen auch berücksichtigen, welche Reichweite der Webdienst haben wird. Der Dienst könnte von Personen auf der ganzen Welt verwendet werden: Was heißt das für Sie?
Unter Umständen haben Sie Probleme beim Speichern und Übertragen der Daten. Wenn Ihr Dienst Zeichenfolgendaten akzeptiert, sollten Sie überprüfen, ob internationale Alphabete (z.B. Japanisch, Kyrillisch, Arabisch usw.) akzeptiert, übertragen und gespeichert werden. Mit dem Favoritendienst haben wir dies so gelöst, dass wir gefordert haben, dass der Dienst UTF-8- und UTF-16-codierte XML akzeptiert. Diese Anforderung wird für uns vom Microsoft SOAP Toolkit Version 2 durchgesetzt. Sie müssen auch über große Zeichensätze nachdenken, wenn Sie Ihre Back-End-Systeme konfigurieren. Verwenden Sie im Hintergrund Unicode-fähige Zeichenfolgentypen und Datenspeichermethoden. Für den Favoritendienst haben wir Visual Basic verwendet, da diese Programmiersprache Unicode-Zeichenfolgen systemeigen unterstützt. Auf der Speicherseite speichern wir alle Zeichenfolgen in Microsoft SQL Server mit Hilfe der Datentypen nchar und nvarchar. Wie Sie sehen, kann die Auswahl der richtigen Tools die Implementierung dieses Aspekts der Internationalisierung wesentlich vereinfachen.
Sie müssen weiterhin berücksichtigen, wie Sie die Dokumentation des Webdienstes bereitstellen. Die meisten Entwickler verfügen über ausreichendes Englisch in Wort und Schrift, so dass Sie eine große Reichweite erzielen, wenn Sie eine gute englische Dokumentation bereitstellen. Verwenden Sie in diesen Dokumenten keine Slangausdrücke, und formulieren Sie einfach und präzise. Damit Ihr Dienst auch in anderen Ländern gut angenommen wird, sollten Sie u.U. auch eine Dokumentation in der Muttersprache des Entwicklers bereitstellen.
Für die Rückgabe von SOAP-Fehlern sollten Sie es den Lizenznehmer(innen) ermöglichen, eine bevorzugte Sprache für das Fault.Description-Element auszuwählen. Ein beträchtlicher Teil der Fehler kann vom Endbenutzer des Dienstes gesehen werden. Wir haben zwar angeregt, die Fehlermeldungen in bestimmten Sprachen bereitzustellen, haben uns jedoch dagegen entschieden. (Nach meinen Informationen widmet sich das Projekt "Lucy" der Übersetzung der Fehlermeldungen - von diesem Projektteam wird im Verlauf dieses Jahres hoffentlich noch eine Diskussion zu diesem Thema angestoßen.) Stattdessen haben wir eine Dokumentation geschrieben, indem wir die Fault.Code-Werte festgelegt haben, die von jeder und allen Funktionen zurückgegeben werden, die der Webdienst offen legt. So können Programmierer Anwendungen implementieren, die den Favoritendienst zum Behandeln von Fehlern und für die Lokalisierung verwenden.
Sie sollten auch überlegen, was passiert, wenn der Webdienst an Popularität außerhalb Ihrer Region gewinnt. Momentan befinden sich die Cold Rooster-Dienste alle in Redmond, WA, USA. Benutzer außerhalb der USA müssen eine transozeanische Internetverbindung öffnen, um diesen Dienst zu verwenden. Wenn die Zahlen es rechtfertigen, müssten wir uns überlegen, den Webdienst auch in anderen Teilen der Welt bereitzustellen, so dass Benutzer schnellere Antwortzeiten erhalten. Mit global verteilten Servern, die Anfragen bearbeiten, machen sich schnell neue Probleme breit. Wenn wir den Webdienst erweitern, müssten wir berücksichtigen, wie die Benutzerdaten verteilt werden.
Für den Favoritendienst führe ich nachfolgend eine Auswahl der Probleme auf, die entstehen könnten:
-
Die Lizenznehmer(innen) erwarten, dass sie auf allen Webservern auf den Webdienst zugreifen können. Wir müssen also Wege finden, die Daten zwischen Datencentern zu synchronisieren.
-
Die Endbenutzer erwarten, dass ihre Daten mit ihnen reisen, egal wohin. Das heißt, wir müssen die Lizenznehmer(innen) dazu bringen, sich zu erinnern, an welches Datencenter sie sich gewendet haben, um Endbenutzerdaten zu erhalten. Oder wir verbreiten alle Benutzerdaten an alle Datencenter.
-
Wo richten wir Überwachungsprotokolle ein, wenn das Überwachen global stattfindet? Sehr wahrscheinlich speichern wir alle Überwachungsdaten in einer Datenbank an einem Speicherort und reihen einfach die Anfragen zu dieser Datenquelle in eine Warteschlange ein, um eventuelle Wartezeitprobleme zu vermeiden.
-
Wir müssen Regeln aufstellen, um in Konflikt stehende Änderungen zwischen Datencentern aufzulösen, die um den ganzen Globus verteilt sind. Eine Lizenznehmerin kann z.B. die Daten für den Administratorkontakt auf zwei unterschiedlichen Servern ändern, und wir müssten dafür Regeln haben, wie dieser Konflikt aufgelöst wird.
Ein letzter Aspekt für die Globalisierung, der übrigens leicht übersehen wird, ist die Entscheidung über die Zahlungsweise. Lassen Sie die Benutzer in jeder Währung bezahlen, oder fordern Sie von ihnen, dass sie in der lokalen Währung bezahlen? Dies kann ein komplexes Globalisierungsproblem sein, und wir möchten es in die Ideenecke für zukünftige Artikel aufnehmen, wenn die Leser Interesse daran haben.
Schlussfolgerung
Wenn Sie einen Webdienst entwerfen, sollten Sie berücksichtigen, wie der Webdienst verwendet wird. Sie können seine Leistung im Netzwerk schon optimieren, indem Sie die WSDL-Datei betrachten, die das Tool für Sie erzeugt. Diese Datei zeigt Ihnen, wo Sie große Datenmengen übertragen, die den Gesamtdurchsatz beeinträchtigen. Sie sollten auch vermeiden, die gesamte Funktionalität Ihres Webdienstes in einen Topf zu werfen, sofern es keinen Sinn macht. Gruppieren Sie verwandte Funktionen in einem Port.
Entwickeln Sie eine Globalisierungsstrategie, und entwerfen Sie für ein breites Publikum. Setzen Sie voraus, dass dieses Publikum eine Vielzahl von Sprachen spricht. Beim Favoritendienst haben wir überprüft, dass wir Zeichenfolgen für Sprachen mit großen Alphabeten (wie Chinesisch) speichern konnten. Sie sollten dasselbe tun, wenn Sie Ihren Webdienst testen. Ermitteln Sie alle Zeichenfolgen, die außerhalb der ersten 128 ASCII-Zeichen liegen, und stellen Sie fest, ob Sie Zeichenfolgen in Chinesisch, Arabisch und einigen anderen Alphabeten speichern und abrufen können. Dies zeigt, wie gut Sie Unicode-Zeichenfolgen mit Ihrem Webdienst unterstützen.
Wenn Sie mehr zu WSDL lesen möchten, empfehlen wir Ihnen die folgenden Artikel:
WSDL-Hintergrundinformationen:
Eine vollständige Liste der deklarierten XML-Datentypen finden Sie unter XML Schema Part 2: Datatypes (in Englisch).