Web-Service-APIs Contest – Teil 2

Entstehung, Aufbau und Funktionsweise von SOAP

Seite: 2/2

Wofür wird SOAP eingesetzt?

SOAP wird in der Praxis meist dann verwendet, wenn ein direkter Zugang „fremder“ Systeme zu einer Informationsquelle nicht gewünscht oder möglich erscheint, etwa weil es zwischen der Architektur von Quell- und Zielanwendung große Kompatibilitätsbarrieren gibt. Aber auch Sicherheitsaspekte sind ursächlich für den Einsatz von SOAP.

Soll z. B. eine komplexe Multi-Tier-Web-Anwendung nur einen partiellen Zugriff auf eine Datenbank-Tabelle erhalten, so muss dank SOAP nicht dem kompletten Anwenderprogramm ein direkter Zugang auf die Tabelle oder gar die ganze Datenbank gestattet werden. SOAP erlaubt es, die Anzahl der ausführbaren Methoden zu definieren bzw. zu reglementieren. Damit zielt der Einsatz von SOAP – ebenso wie der von REST – auf die sogenannte „lose Kopplung“ von Systemen.

Vor und Nachteile von SOAP

SOAP ist zwar sehr komplex, allerdings verwenden Entwickler in der Regel nur jene Teile/Aspekte, die sie zur Lösung einer bestimmten Aufgabe benötigen. Zur Implementation eines öffentlichen Web-Dienstes, der frei für jedermann verfügbar ist, muss man sich beispielsweise nicht mit WS-Security auseinandersetzen.

Auf der anderen Seite kann der XML-Code zur Formulierung von Anfragen und das Erhalten von Antworten in SOAP extrem komplex werden. Je nach verwendeter Programmiersprache müssen solche Anfragen manuell erstellt werden. Das ist wiederum nicht unproblematisch, weil SOAP nicht sonderlich fehlertolerant ist.

Für ausgewählte Sprachen stellt SOAP allerdings Verknüpfungen (z. B. zu WDSL) bereit, was wiederum den Aufwand zum Erstellen einer Anfrage und Analysieren der Antwort reduziert. Bei .NET-Sprachen beispielsweise kommt man mit XML quasi nicht in Berührung.

Die Architektur von WSDL.
Die Architektur von WSDL.
(Bild: IBM)

Einen großen Anteil an dieser „Magie“ hat die Web Services Description Language (WSDL). Hierbei handelt es sich um eine plattform-, programmiersprachen- und protokollunabhängige Beschreibungssprache für Netzwerkdienste (Webservices) zum Austausch von Nachrichten auf XML-Basis.

Auch die Meta-Sprache WSDL ist ein Industriestandard des W3C. Eine WDSL-Datei beschreibt in SOAP die Schnittstellen von Web-Services, also wie der Dienst funktioniert und wie Nachrichtenstrom-Formate sowie Funktionsaufrufe definiert sind.

Eine solche WDSL-Datei lässt sich z. B. automatisch aus Java-Source-Dateien erzeugen. Erstellt man also in der eigenen IDE einen Verweis auf die WDSL-Datei, kann die IDE den Prozess der Generierung des XMLs quasi vollständig automatisieren. Faktisch hängt also der Schwierigkeitsgrad bei der Verwendung von SOAP in hohem Maße von der verwendeten Sprache ab.

Im Prinzip ist die Handhabung von SOAP ohne WDSL gar nicht praktikabel. So hat Microsoft beispielsweise erst im Oktober 2016 eine Möglichkeit für Azure-Kunden geschaffen, dass diese über das Azure-API-Management eine Art Proxy für ihre SOAP-APIs erstellen können, ähnlich wie das bereits für REST-APIs möglich war.

Das funktioniert allerdings nicht ohne WDSL-File, weil das Erstellen von SOAP-Services „from scratch“ im Vergleich zu REST viel zu komplex ist. Matt Farmer hat dazu ein sehenswertes Video im MSDN-Blog von Microsoft veröffentlicht.

Bereits erwähnt wurde die Flexibilität von SOAP bei der Auswahl des Transport-Protokolls. Zwar kommt HTTP/S am häufigsten zum Einsatz, es gibt aber in der Tat auch Spezifikationen für die Verwendung von SMTP oder FTP. Python- und PHP-Entwickler machen durchaus auch Gebrauch davon.

Fehlerbehandlung

Ferner gehört die integrierte Fehlerbehandlung sicher zu den Vorzügen von SOAP. Gibt es beispielsweise ein Problem mit eine Anfrage, finden sich in der Antwort brauchbare Fehlerinformationen, die zur Behebung des Problems verwendet werden können.

Angesichts der Tatsache, dass man ja nicht der Eigentümer, bzw. Ersteller des angefragten Web-Services ist, ist dies eine äußerst wichtige Hilfestellung. Die Fehlerberichterstattung liefert sogar standardisierte Codes, so dass es möglich ist, einige Fehlerbehandlungsaufgaben im eigenen Code zu automatisieren.

Die SOAP-Kommunikation

SOAP ermöglicht den Aufbau „schwach“ gekoppelter Systeme. Diesen Vorteil in der Flexibilität erkauft man sich allerdings mit Nachteilen beim Übertragungsvolumen und im Rechenaufwand, weil das XML-Dokument zunächst beim Sender aufgebaut und danach validiert werden muss.

Ein weiteres Manko ist, dass die zu übertragende Datei im Verlauf der Konstruktion des XML-Dokuments mit einer ganzen Reihe von Metadaten angereichert wird. So führt das einfache Versenden einer True/False-Information in einem schwach gekoppelten System zu einem extrem hohen Datenvolumen, wozu bei einem stark gekoppelten oder monolithischen System ein Bit ausreichen würde.

Das andere Extrem: der flexible Aufbau des Dokuments erlaubt es, auch sehr komplexe Transaktionen in einer einzigen Anfrage zu formulieren, wozu bei stark gekoppelten Systemen meist mehrere Anfragen gestellt werden müssen. Somit verbessert sich bei komplexen Transaktionen das Verhältnis von Nutzdaten zu Metadaten erheblich, während der Kommunikationsaufwand für den Aufbau einer Verbindung gleich bleibt.

Übrigens unterscheidet SOAP zwischen endgültigem Empfänger und Zwischenstationen. So lassen sich Nachrichten über verschiedene „Hops“ versenden, sogar wenn dabei verschiedene Transportprotokolle zum Einsatz kommen; im Gegensatz zur Middleware benötigt der Absender dabei keinerlei Information zu den Zwischenstationen.

Die Kommunikationsstile von SOAP.
Die Kommunikationsstile von SOAP.
(Bild: Slideplayer)

Neben dem erwähnte Message-Style (oder Document-Style) unterstützt SOAP auch einen an RPC angelehnten Communication-Style. Ein Codebeispiel für einen Document-Style-SOAP-Body könnte etwa so ausehen:

<strong><types>
   <schema>
   <element name="xElement" type="xsd:int"/>
   <element name="yElement" type="xsd:float"/>
   </schema>
</types></strong>
<message name="myMethodRequest">
   <part name="x" <strong>element="xElement"</strong>/>
   <part name="y" <strong>element="yElement"</strong>/>
</message>
<message name="empty"/><portType name="PT">
   <operation name="myMethod">
   <input message="myMethodRequest"/>
   <output message="empty"/>
   </operation>
</portType>
<binding .../>

(ID:44607740)