<wsdl:types>
<s:schema elementFormDefault="qualified" targetNamespace="http://WeatherService.Schema">
<s:element name="GetWeather">
<s:complexType>
<s:sequence>
<s:element minOccurs="0" maxOccurs="unbounded" name="Zip" type="s:string" />
< SPAN <>< SPAN>s:sequence>
< SPAN <>< SPAN>s:complexType>
<< SPAN>s:element>
<s:element name="GetWeatherResponse">
<s:complexType>
<s:sequence>
<s:element minOccurs="0" maxOccurs="unbounded" name="WeatherInfo" type="s1:WeatherInfoType" />
<< SPAN>s:sequence>
< SPAN <>< SPAN>s:complexType>
< SPAN <>< SPAN>s:element>
<s:complexType name="WeatherInfoType">
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" name="Temperature" type="s:integer" />
<s:element minOccurs="0" maxOccurs="1" name="Humidity" type="s:integer" />
<s:element minOccurs="0" maxOccurs="1" name="WindSpeed" type="s:string" />
<s:element minOccurs="0" maxOccurs="1" name="Conditions" type="s:string" />
< SPAN <>< SPAN>s:sequence>
<s:attribute name="Zip" type="s:string" />
< SPAN <>< SPAN>s:complexType>
< SPAN <>< SPAN>s:schema>
< SPAN <>< SPAN>wsdl:types>
Surprisingly, to get a weather report we are not required to pass parameters as Zip element became an optional one. Also, its value is no longer restricted to 5 characters length. The same striking change is seen in the response definition: all fields of the WeatherInfo element are optional now. What a big change in our service interface! Would you want to share such contract that lacks original fidelity? I wouldn’t.
Of course, what we’re observing here is a typical example of so called “impedance mismatch” between XML Schema and object-oriented worlds. Whenever mapping entities from one domain to another we have to deal with differences between document-centric and object-centric models plus variations imposed by specific type system implementation. In our case, we got this effect because BizTalk first generated .Net types (DataTypes.cs) and service endpoint code (WeatherService.asmx.cs). Then .Net framework generated WSDL from this code when we hit the service URL. Thus, original schema got distorted by .Net common type system view of the world.
Therefore, BizTalk schema publishing supports development flow as depicted below. The picture below shows parts of a service contract in blue while implementations in yellow. Notice how WSDL is no longer an abstract service description but rather description of concrete service endpoint:
However, when doing contract-first development, we want to create artifacts that belong to service contract before any implementation begins. This way, the WSDL preserves original type definitions, without exposing consumers to service implementation domain:
This is why just publishing schemas in BizTalk is not true contract-first development.
So, does BizTalk still allow designing a contract-first way? Yes, it does. Remember, we started from XML messages schema which is a part of the service contract.
Does it strictly follow contract-first development flow? No, because it creates part of the service contract (WSDL) based on premature platform specific implementation (service endpoint) which hinders original types’ definitions.
Is it possible to work around this limitation? Yes, we can disable dynamic WSDL generation and provide static WSDL that imports original unaltered schema:
<wsdl:types>
<xsd:schema>
<xsd:import schemaLocation="MyTypes.xsd" namespace="http://weather.services"/>
< SPAN <>< SPAN>xsd:schema>
< SPAN <>< SPAN>wsdl:types>
Another way is to author WSDL and import it using BizTalk BPEL import project.
Are there any other practical considerations when doing contract-first development with BizTalk? Yes, stay tuned for the next article.