Když jsem psal minule o
verzování SOAP webových služeb, zaměřil jsem se pouze na verzování v rámci
WSDL. Letmo jsem také popsal WSDL strukturu, s tím, že jsem nijak neřešil definici datových typů. Tady se může skrývat další úskalí (nebo příležitost pro) verzování.
Datové typy jsou uvedeny v elementu
types. Pokud není definice typů triviální, nebo pokud není ve službě definovaná pouze jedna operace, tak se zpravidla drží definice externě v XSD souboru a do WSDL se pouze naincludují (pokud chceme mít typy ve stejném namespace, jako má WSDL), nebo naimportují (pokud chceme, aby XSD mělo samostatný namespace).
Myslím, že je lepší používat element
import. Kromě toho, že je to podmínka, aby kontrakt splňoval
WS-I Basic Profile, tak to umožňuje dodržovat následující konvenci:
- Součástí namespace WSDL je název služby.
- Každá operace má svoje vlastní XSD (v němž je definovaný request a response).
- Součástí namespace XSD je název služby a název operace.
- Plus samozřejmě verzujeme.
Takže pokud bysme měli službu s názvem
MyService a operaci s názvem
myOperation, tak by namespacy vypadaly takto:
WSDL:http://sw-samuraj.blog/ws/MyService-v1XSD:http://sw-samuraj.blog/ws/MyService-v1/myOperationPodobně jako u WSDL, je v namespace uvedena pouze
major verze a jelikož je už ji obsahuje název služby (MyService-
v1), není potřeba ji duplikovat ještě v názvu operace.
Kromě namespaců verzujeme také samotný XSD soubor, např.
myOperation-v1.2.xsd. Což nás staví před následující dilema. Představme si, že máme službu, která obsahuje dvě operace. Něco jako:
xml version="1.0" encoding="UTF-8"
<definitions
targetNamespace=
"http://sw-samuraj.blog/ws/MyService-v1"
xmlns="http://schemas.xmlsoap.org/wsdl/"
xmlnssoap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlnsxsd="http://www.w3.org/2001/XMLSchema">
<types>
<xsdschema>
<xsdimport
namespace=
"<trimmed>/MyService-v1/myOperation"
schemaLocation="xsd/myOperation-v1.2.xsd"/>
<xsdimport
namespace=
"<trimmed>/MyService-v1/yourOperation"
schemaLocation="xsd/yourOperation-v1.2.xsd"/>
</schema>
</types>
<portType name="MyServicePort-v1.2">
<operation name="myOperation">
</operation>
<operation name="yourOperation">
</operation>
</portType>
</definitions>
Dilema zní: pokud dojde ke změně kontraktu pouze v rámci jedné operace, změním verzi pouze u XSD, které této operaci odpovídá, nebo změním verzi u všech XSD, které jsou součástí kontraktu? (V obou případech samozřejmě verzujeme WSDL tak, jak bylo uvedeno v předešlém článku.)
Pokud by se nám změnila operace
myOperation, tak v prvním případě by import vypadal takto:
<types>
<xsdschema>
<xsdimport
namespace=
"<shortened>/MyService-v1/myOperation"
schemaLocation="xsd/myOperation-v1.3.xsd"/>
<xsdimport
namespace=
"<shortened>/MyService-v1/anotherOperation"
schemaLocation="xsd/anotherOperation-v1.2.xsd"/>
</schema>
</types>
<portType name="MyServicePort-v1.3">
Výhodou této volby je, že verzujeme pouze XSD, u nichž opravdu došlo ke změně, zbytek necháváme na pokoji. Nevýhodou je, že verze XSD se nám rozjedou - jednak vůči sobě a jednak vůči WSDL. Reálně pak
verzujeme XSD jako samostatný artefakt a ne jako součást kontraktu. To může být korektní situace, někdy vznikají XSD bez vazby na WSDL - v rozsáhlých projektech jsou často XSD vytvářena týmy analytiků a jejich import do WSDL zajišťují vývojáři.
V případě druhé možnosti by import vypadal následovně:
<types>
<xsdschema>
<xsdimport
namespace=
"<shortened>/MyService-v1/myOperation"
schemaLocation="xsd/myOperation-v1.3.xsd"/>
<xsdimport
namespace=
"<shortened>/MyService-v1/anotherOperation"
schemaLocation="xsd/anotherOperation-v1.3.xsd"/>
</schema>
</types>
<portType name="MyServicePort-v1.3">
Nevýhodou této možnosti je, že musíme převerzovat všechy XSD v kontraktu, i ty, které se nezměnily (což se může zdát nepřirozené). Výhodou je, že
kontrakt má jednotné verzování, takže mmj. nemusím kontrolovat jestli mám všechny XSD ve správné verzi. Zároveň je explicitně řečeno, že XSD je součástí kontraktu (ve smyslu
objektové kompozice) a kontrakt (WSDL + XSD) by měl být vytvářen jedním týmem.
U nás na projektu o tom byla poměrně bouřlivá diskuze, kterou variantu zvolit. Argumenty byly poměrně vyrovnané a více méně odpovídaly těm uvedeným výše. Nakonec jsme se rozhodli pro jednotný kontrakt, takže se změnou verze WSDL převerzováváme i všechny XSD.