Monday, February 13, 2017

Most common WSDL stumbling block

Most common WSDL stumbling block


When it comes to helping people debug WSDL issues, the #1 overlooked and misunderstood problem is usually whether to specify type or element as the attribute to the element. If you are creating web services and defining WSDLs you must understand this significant difference as it will effect the consumers of your services.

All my examples and information where referenced from the book Building Web Services with Java. I would highly recommend this book.

Simple WSDL
Lets first begin with snippets from a simple WSDL.
<definitions name="PriceCheck">
<types>
<xsd:schema>
<xsd:element name="sku" type="xsd:string"/>
<xsd:complexType name="availabilityType"
<xsd:sequence>
<xsd:element ref="sku"/>
<xsd:element name="price" type="xsd:double"/>
<xsd:element name="quantityAvailable" type="xsd:integer"/>
</xsd:sequence>
</xsd:complexType>
<xsd:element name="StockAvailability" type="availabilityType"/>
</xsd:schema>
</types>
<message name="PriceCheckRequest">
<part name="sku" element="sku"/>
</message>
<message name="PriceCheckResponse">
<part name="result" element="StockAvailability"/>
</message>
<portType>
<operation name="checkPrice">
.......
<binding>
.......
<service>
.......
</definitions>
WSDL Parts
A part element is made up of two properties: the name of the part and the kind of the part. The name property is represented by the name attribute, which must be unique among all the part child elements of the message element. The kind property of the part is defined as either a type attribute (a simpleType or complextType from the XSD schema type system) or an element attribute (also defined by referring to an element defined in the XML schema). You cant use both an element attribute and a type attribute to define the same part.

The choice of using element or type when defining the part is very important. The most common mistake is using the type attribute and referencing an XSD element or using the element attribute and referencing an XSD simpleType or complexType.

Use of element
When you use the element attribute, youre specifying that the SOAP should be precisely that XML element. For example, the PriceCheckRequest example specifies that the XML element named sku must be used as the body of the messsage. Here is a snippet of what the SOAP would look like:

<soap:Envelope>
<soap:Body>
<sku>123</sku>
</soap:Body>
</soap:Envelope>
Note how the SOAP contains exactly the specified sku element. The element attribute should be used to define the type of the part when the Web service is meant to be document oriented (which is defined in the binding). Whenever the element attribute is used, its value must refer to another global XML element defined or imported in an XML schema.

This not only applies to requests but responses as well. For example, here is what the SOAP would look like for PriceCheckResponse:

<soap:Envelope>
<soap:Body>
<StockAvailability>
<sku>123</sku>
<price>100.0</price>
<quantityAvailable>12</quantityAvailable>
</StockAvailability
</soap:Body>
</soap:Envelope>

Use of type
The PriceCheckRequest could have been built differently, using a part defined with the type attribute, like this:

<message name="PriceCheckRequest">
<part name="sku" type="xsd:string"/>
</message>

Here is an example of the SOAP using the RPC-style where checkPrice is the name of the operation defined in the WSDL:

<soap:Envelope>
<soap:Body>
<checkPrice >
<sku xsi_type="xsd:string">123</sku>
</checkPrice>
</soap:Body>
</soap:Envelope>
Summary
That is the difference between defining your part as an element or type. The most common style to use is document oriented and therefore the parts must use elements. If you use type in your parts, you need to use the RPC style.

Unfortunately all this isnt well documented. However there is good news. In WSDL 2.0 message and part elements have been removed. Instead you would use the names of the XML element declarations directly in the operations input, output, and fault messages.

Available link for download