Early in life, we learn that a postal stamp belongs in the upper-right corner of an envelope and that the address goes somewhere in the center. If we want, we can also add a return address in the upper-left corner of the envelope. All mail handled by the postal service must adhere to this basic structure. If mail is not metered, a delivery address is not present, or the delivery address is illegible, the postal service considers the mail invalid and will not deliver the letter. If we’re lucky, invalid mail will be delivered to the return address (if one is specified). Imagine the chaos that would follow if such a structure did not exist. If senders were allowed to place postage or delivery addresses anywhere on the parcel, the postal service would have to scan the entire parcel for postage and delivery addresses. More than likely, the added infrastructure required to complete these tasks would add more than a couple of cents to the next postage rate hike! In practice, the parcel structure as defined by the postal service improves mail handling efficiency and consistency without sacrificing much usability from the sender’s perspective.
In contrast to the postal example, SO messages do not have to follow structural pattern. Like the postal example, however, a predefined message structure does improve the processing efficiency, reliability, and functionality of the system. Remember that messaging applications are not conceptually new. Messages originating from a variety of application vendors have been passed between applications for decades. Without a standardized structure, each vendor is free to develop its own structure, and the result is a disparate set of message structures that do not interoperate well with one another.
If we look at companies like FedEx, UPS, and DHL, we see a similar paradigm. Each of these organizations has defined its own addressing format and packaging. It is atypical for an overnight package in a UPS box with a UPS label to be sent via FedEx. Technically it is possible, but business pressures and efficiency preclude these companies from interacting with another type of address and parcel format.
It’s not a huge leap to examine purchasable enterprise computing systems with the same concept. On the whole, vendors have not wanted their applications to interoperate with other systems. Vendors had a hard enough time getting their systems to communicate within a single product suite, let alone interoperate with other systems. In the past, customers were willing, to some extent, to stick within one particular application vendor’s toolset to meet all of their enterprise needs. The choice customers faced was one of “Who can sell me the complete package?” rather than “What products are the best for each of my needs?” Over time, the one-stop-shopping paradigm has resonated less and less with would-be customers. As a result, software vendors have had to come to the table to produce a series of common messaging specifications and standards and make their applications produce messages that adhere to these standards. It has taken many years for these standards to be created and agreed upon, but they are finally here, and we can expect more over time.
There are literally dozens of these messaging standards available, and we will examine many of these specifications as you move through this book. Many of these specifications are based, in one form or another, on SOAP, and each serves a specific purpose. For the intellectually curious, the full SOAP specification is available at http://www.w3.org/TR/soap12-part1/. As a result of SOAP’s flexibility, modern SO messages are usually SOAP messages.[1] At its core, SOAP is a messaging structure built on XML. SOAP defines three major XML elements that can be used to define any XML message you want to send: the envelope, the body, and the header. Here is an example of the key parts of a raw SOAP message:
<?xml version='1.0' ?> <env:Envelope xmlns:env="http://www.w3.org/2003/05/soap-envelope"> <env:Header> ... </env:Header> <env:Body> ... </env:Body> </env:Envelope>
Because WCF is an SO platform intended for, among other things, interoperability with other systems, it sends, receives, and processes SOAP messages. As you’ll see in Chapter 4, “WCF 101,” we can think of WCF as a toolkit for creating, sending, and parsing SOAP messages with a myriad of different behaviors. For now, let’s take a closer look at what all SOAP messages have in common.
As its name implies, the envelope wraps both the body and the header. All SOAP messages have an envelope as a root element. The envelope element is often used to define the different namespaces (and prefixes) that will be used throughout the message. There is not much else that’s terribly exciting about SOAP envelopes.
A SOAP header is optional and, if present, it must be the first element after the envelope start tag. A SOAP header is composed of zero or more SOAP header blocks. SOAP header blocks contain information that can be used by the ultimate receiver or by an intermediary. Typically these header blocks contain data that is orthogonal to the message body’s data. To put it another way, security information, correlation, or message context can be placed in a header part. Header blocks are mandatory if certain messaging behaviors are expected. Once again, this idea can be illustrated through the postal system. If I want to send a piece of mail through the postal system and receive a return receipt when the parcel is delivered, I have to fill out a special return receipt label and affix it to the envelope. Adding a return receipt to the parcel does not materially change the contents of the parcel. It can, however, change the behavior of messaging participants: I have to fill out and affix the return receipt request, the postal carrier must ask for a signature, the ultimate receiver must sign the receipt, and the postal carrier must deliver the receipt to me (or at least my mailbox).
SO messages can contain similar information in the header. For example, in our order processing scenario, the Web site might want to receive a confirmation that the order message was received by an entity other than the message router. In this case, the Web site could assign a unique identifier to the message and add a special header to the message requesting an acknowledgment. Upon receipt, the message router forwards the message on to the appropriate system and demands that the system produce an acknowledgment. That acknowledgment could then be returned to the Web site directly or through the message router.
It is also possible that an intermediary might modify an existing SOAP header block or even add a brand new SOAP header block to a message. In practice, however, an intermediary should never change or delete a header block unless it is intended for them. Using this model, it would be fairly easy to create a message that contains auditable records of its path. Each intermediary can add its own SOAP header, so by the time the message arrives at the ultimate receiver, the message contains a list of all intermediaries that have touched the message. As described earlier, this behavior is modeled in the real world in the postal system with postmarks or as described in our message router example.
The body element is mandatory and typically contains the payload of the message. By convention, data found in the body is intended for the ultimate receiver only. This is true regardless of how many firewalls, routers, or other intermediaries process the SOAP message. This is only an informal agreement. Just as there is no guarantee that the postal service will not open our mail, there is no guarantee that an intermediary will not open or change the SOAP body. It is possible, however, to use digital signatures and encryption to digitally ensure the integrity of a message as it passes from initial sender to ultimate receiver.
[1] WCF supports SOAP, REST, and POX. Most of the current WCF application programming interface (API), however, is dedicated to the SOAP message structure. This will undoubtedly expand in the future to include other message structures, like JSON.