Monday, October 19, 2009

Contract-First Web Services in practice - part 2 of 5

This is article is the second part of a five article series on a working example of SOA at work. In the last article I introduced the challenge, coming up with a fairly robust WSDL which could be implemented in multiple different programming languages consistently.

The service we are creating has one operation. The input for this sample operation takes an xml message with one element as well as an array of a nested object. The output returns an array of the same input objects (I had to redact the more meaningful input and output messages as they were work related). It initially seems complicated because I'm trying to capture all the complexities of xml structures and how the map to data structures that programmers in modern programming languages often take for granted. Ok, enough introduction, let's get onto the WSDL.

Click the expand source link and voila! That's the WSDL. Now to run you through the xml elements that constitute this WSDL.

Exceptions in SOAP are xml messages that can be defined in the schema. For this example, the exception is aptly named ServiceException, and it has an element named "message" which happens to be a string.

  1. <!-- Exception message, contains a string with the field message -->
  2. <xsd:complexType name="ServiceException">
  3. <xsd:sequence>
  4. <xsd:element name="message" nillable="true" type="xsd:string"/>
  5. </xsd:sequence>
  6. </xsd:complexType>
Arrays & Collections
There are several ways to represent arrays in XML. I've chosen for this sample, the simplest way which is to use the xml attribute "maxOccurs" and set it to "unbounded".
  1. <!-- A sample field with two elements, FieldName and FieldValue -->
  2. <xsd:complexType name="SampleField">
  3. <xsd:sequence>
  4. <xsd:element minOccurs="1" maxOccurs="1" name="FieldName" type="xsd:string"/>
  5. <xsd:element minOccurs="1" maxOccurs="1" name="FieldValue" type="xsd:string"/>
  6. </xsd:sequence>
  7. </xsd:complexType>
  8. <!-- An array of sample fields -->
  9. <xsd:complexType name="ArrayOfSampleField">
  10. <xsd:sequence>
  11. <xsd:element minOccurs="0" maxOccurs="unbounded" name="SampleField" nillable="true" type="tns:SampleField"/>
  12. </xsd:sequence>
  13. </xsd:complexType>
Declarative SOAP Exceptions
For this sample, soap exceptions are declared in the WSDL, this is in order to detect multiple exceptions. In this sample, we only have ServiceException, but could have included others, to programmatically detect which exception was thrown. This declaration is achieved by using the "fault" element. Note that the exception needs to be declared in both the binding and port type.
  1. <binding name="SampleServiceBinding" type="tns:SampleServicePortType">
  2. <soap:binding style="document" transport=""/>
  3. <operation name="SampleOperation">
  4. <soap:operation soapAction="urn://SampleService#SampleOperation"/>
  5. <input>
  6. <soap:body use="literal"/>
  7. </input>
  8. <output>
  9. <soap:body use="literal"/>
  10. </output>
  11. <fault name="ServiceException">
  12. <soap:fault name="ServiceException" use="literal"/>
  13. </fault>
  14. </operation>
  15. </binding>
That's it for the most part. In the next article, I'll be looking at the PHP implementation of this WSDL.

No comments: