In the previous section we established that a WSDL definition intentionally separates abstract from concrete definition details. One of the benefits of doing so is that we can isolate communication protocols that implement the messaging required by a service from the implementation-neutral service interface. However, given that SOAP has become the messaging format of choice for SOA, we will very likely be binding our abstract interfaces to SOAP.
Within the service-oriented design process, we place a great deal of emphasis on hand crafting the WSDL definition, along with required XSD schema types. SOAP messages generally do not require as much hands on attention. We spend more time working with SOAP syntax in Chapter 17, where we explore WS-* extensions that are implemented via SOAP headers. Still, this is as good of a time as any to introduce some basic parts of the SOAP language.
As we established in Chapter 5, the structure of SOAP messages is relatively simple. They consist of header, body, and fault sections, all encased in an envelope. Appropriately, the elements we describe in this section (Figure 13.5) are represented by the same names. (The manner in which SOA affects the utilization of SOAP is explored in the SOAP and SOA section in Chapter 14.)
Figure 13.6. The structure of a SOAP message document.
13.4.1. The Envelope element
The Envelope element represents the root of SOAP message structures. It contains a mandatory Body construct and an optional Header construct.
Example 13.18. The root Envelope construct hosting Header and Body constructs.
<Envelope xmlns ="http://schemas.xmlsoap.org/soap/envelope/">
13.4.2. The Header element
As explained in Chapter 5, the header portion of the SOAP message has become a key enabler of the feature set provided by WS-* specifications. Most of these extensions are implemented on a message level and introduce new standardized SOAP header blocks destined to be embedded in the Header construct.
Example 13.19. The Header construct hosting a header block.
<Header> 0131858580-JDJ903KD Header>
Header blocks also can be customized, as shown in Example 13.19, where the SOAP header is used to host a unique CorrelationID element. The mustUnderstand attribute indicates that the contents of the header must be understood by any receiver of the message that is required to process this header. If the mustUnderstand value is set to "0" the processing of this header becomes optional.
13.4.3. The Body element
This is the one required child element of the SOAP Envelope construct. It contains the message payload formatted as well-formed XML. The structure and naming used to define this part of the SOAP message relates to the style and use attributes discussed in the previous WSDL binding element description.
SOAP message Body constructs are defined within the WSDL message constructs which, as we've already established, reference XSD schema data type information from the WSDL types construct (Figure 13.7).
Figure 13.7. A SOAP message body defined within the WSDL message construct. The actual processing of the SOAP message via a wire protocol is governed by the constructs within the concrete definition.
Example 13.20. The contents of a sample Body construct.
<Body> 0131858580 Service-Oriented Architecture Concepts, Technology, and Design Body>
While SOAP header blocks can be processed actively during the transmission of a SOAP message, the SOAP body should not be touched. However, if allowed, intermediary services can still read and derive information from body content. For example, a correlation identifier used in a SOAP header can be generated based on the ISBN value shown in the preceding example.
13.4.4. The Fault element
The optional Fault construct provides a ready made error response that is added inside the Body construct. In the example that follows, this fault information is further sub-divided using additional child elements. The faultcode element contains one of a set of fault conditions predefined by the SOAP specification. Both the faultstring and detail elements provide human readable error messages, the latter of which can host an entire XML fragment containing further partitioned error details.
Example 13.21. The Fault construct residing within the Body construct.
<Fault> MustUnderstand header was not recognized The CorrelationID header was not processed by a recipient that was required to process it. Now a fault's been raised and it looks like this recipient is going to be a problem. Fault>
In our example a Fault construct is provided to respond to a MustUnderstand violation that may occur when a service expected to process the message correlation identifier fails to do so.
SUMMARY OF KEY POINTS