# [SOAP] Generische vs. spezifische Operationen?



## dasteph (9. November 2007)

Hallo Gemeinde,

folgende Fragestellung:

Ich habe eine Datenbank, die mir Geographische Informationen zu Flughaefen vorhaelt. Dazu habe ich folgende Struktur:

Flughafen ---liegt in---> Stadt ---liegt in---> Land ---liegt auf---> Kontinent

Nun moechte ich Benutzern die Moeglichkeit geben, dieses zu administrieren, ohne Ihnen die Datenbank offenzulegen. In einen bestehenden Client integriert braucht diese Administrations-Oberflaeche einen Webservice, ueber den die Verwaltung laeuft. (Dieser Punkt ist indiskutabel ;-) )

Nun stellt sich mir die Frage, wie ich den Webservice am sinnvollsten/besten/performantesten/etc. designe, damit ich dies spaeter auch der Allgemeinheit zur Verfuegung stellen kann:

*Moeglichkeit A*: spezifisch

Fuer jede der vier Tabellen (Flughafen, Stadt, Land, Kontinent) 3 Operationen:
- insert
- get
- update
==> 12 Funktionen = 24 einfach strukturierte SOAP-Request/Response-Objekte

Zum Anlegen eines Flughafens mit allen Abhaengigkeiten waeren also 4 Anfragen notwendig.


*Moeglichkeit B*: generisch

Es gibt nur eine Operation, der ueber Parameter gesagt wird, was sie im Hintergrund ausfuehren soll.

Parametrisiert kann sie alles, was ich brauche; Ich schiebe alles rein und sie pflueckt den Request auseinander, identifiziert Abhaengigkeiten, sortiert um, und fuehrt schliesslich alles aus. Bei Fehlern rollt sie alle Aenderungen wieder zurueck.

==> 1 Funktion = 2 hochkomplexe Request/Response-Objekte

*Moeglichkeit C*: Meet in the middle 1

Eine generische Operation pro Tabelle, die
- insert
- get
- update
wie Methode B ausfuehrt, aber nur jeweils auf begrenzten Daten operiert.

==> 4 Funktionen = 8 komplexe Request/Response-Objekte

*Moeglichkeit D*: Meet in the middle 2

Eine generische Operation pro Aktion, die alle vier Tabellen bearbeiten kann und dabei die Abhaengigkeiten aufloesen kann

==> 3 Funktionen = 6 komplexere Request/Response-Objekte


Das war noch ziemlich Abstrakt, deswegen (vereinfachte) Request-Beispiele fuer das Anlegen eines Flughafens (JFK/New York/USA/North America):

*Moeglichkeit A:*

Request 1/4: 
    <insertContinent>North America</insertContinent>

Request 2/4: 
    <insertCountry continent="North America">USA</insertCountry>

Request 3/4:
    <insertCity country="USA">New York</insertCity>

Request 4/4:
    <insertAirport city="New York">JFK</insertAirport>

*
Moeglichkeit B:*
Request 1/1:
    <action type="insertCountry" parent="North America">USA</action>
    <action type="insertAirport" parent="New York">JFK</action>
    <action type="insertContinent" parent="">North America</action>
    <action type="insertCity" parent="USA">New York</action>

*Moeglichkeit C:*
Request 1/4: 
    <countryAction type="insert" parent="North America">USA</countryAction >

Request 2/4: 
    <airportAction type="insert" parent="New York">JFK</airportAction >

Request 3/4:
    <continentAction type="insert" parent="">North America</continentAction >

Request 4/4:
    <cityAction type="insert" parent="USA">New York</cityAction >


*Moeglichkeit D:*
Request 1/1:
    <insert airport="JFK" city="New York" country="USA" continent="North America" />
(Anmerkung: <insert airport="" city="New York" country="USA" continent="" /> wuerde nur "New York" in "USA" anlegen und einen Fehler werfen, wenn USA nicht existieren sollte)



Moeglichkeit D scheint mir sehr elegant, daher habe ich gleich mal versucht, das in eine XSD zu giessen.


```
<complexType name="NewContinent">
		<sequence>
			<element name="NAME" type="string"></element>
		</sequence>
	</complexType>

	<complexType name="NewCountry">
		<sequence>
			<element name="ISOCODE" type="string"></element>
			<element name="NAME" type="string"></element>
			<choice>
				<element name="newCONTINENT" type="tns:NewContinent"></element>
				<element name="CONTINENT" type="string"></element>
			</choice>
		</sequence>
	</complexType>

	<complexType name="NewCity">
		<sequence>
			<element name="IATA" type="string"></element>
			<element name="NAME" type="string"></element>
			<choice>
				<element name="COUNTRY" type="string"></element>
				<element name="newCOUNTRY" type="tns:NewCountry"></element>
			</choice>
		</sequence>

	</complexType>

	<complexType name="NewAirport">
		<sequence>
			<element name="IATA" type="string"></element>
			<element name="NAME" type="string"></element>
			<choice>
				<element name="CITY" type="string"></element>
				<element name="newCITY" type="tns:NewCity"></element>
			</choice>
		</sequence>

	</complexType>
```

Die Anfrage saehe dann so aus:


```
<complexType name="Request">
	<choice>
		<element name="AIRPORT" type="tns:NewAirport"></element>
		<element name="CITY" type="tns:NewCity"></element>
		<element name="COUNTRY" type="tns:NewCountry"></element>
		<element name="CONTINENT" type="tns:NewContinent"></element>
	</choice>
</complexType>
```

Meine Frage an die Experten/Erfahrenen: Ist das elegant/praktikabel/verstaendlich genug, dass durch die Definition in der XSD die Funktionalitaet sauber dokumentiert ist?

Gruss

Stephan


----------

