
Processing SOAP Headers
by Rich SalzJuly 17, 2002
SOAP structures a message into two main parts: the headers and the body. I'll go out on a limb and say that almost all SOAP messages so far use the body. Very few put anything in the SOAP headers. I think the recent flurry of activity in SOAP security standards means that this will soon change, however, so it's worth understanding when and how to use SOAP header elements.
SOAP is more than just a sender-receiver protocol, although that, too, is certainly the dominant use today. SOAP supports the concept of a message passing from a recipient, possibly through one or more intermediaries, and ending up at its destination, more precisely known as the ultimate receiver.
|
Related Reading
Programming Web Services with SOAP |
Along the way, the intermediaries may perform processing on the message or its side-effects. For example, a message may pass through a transaction service, providing a client with guaranteed invocation in the presence of network failures; a security service may sit at an enterprise portal, providing authentication information; and so on.
An important aspect of these examples is that the basic operation is unchanged. While this isn't made explicit in the SOAP specifications, it's commonly accepted that intermediaries are intended to work primarily on the metadata of the SOAP message. SOAP headers are the ideal place for such data.
SOAP headers are also a good place to put optional information, and a good means to supporting evolving interfaces. For example, I use my ATM card to get money from my checking account. After several years, my bank upgraded to provide account linking, so that I can manage multiple accounts with one card. If I use my bank's ATM, I now have to specify if I want the withdrawal to be made from my primary, secondary, or tertiary account. If I use an ATM from another bank that isn't affiliated with my bank, I don't get asked that question. So the account identifier is clearly an optional parameter, with a reasonable default.
This is an ideal use-case for SOAP headers. We can define an element to specify an account:
<xsd:element name="AccountSubIdentifier" type="xsd:int"/>
We could then imagine a SOAP message which used that header:
<SOAP-ENV:Envelope>
<SOAP-ENV:Header>
<tns:AccountSubIdentifier>1</tns:AccountSubIdentifier>
</SOAP-ENV:Header>
<SOAP-ENV:Body>
<tns:Action>withdrawal</tns:Action>
<tns:Amount>100</tns:Amount>
<tns:Fee>1.50</tns:Fee>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
Since a SOAP message may pass through several intermediaries and intermediaries are supposed to look at the headers, we need a way to specify which headers are intended for which intermediary. In SOAP this is done by using the "SOAP-ENV:actor" attribute. (It's a named "role" in SOAP 1.2.) The attribute value is a URI that somehow identifies the header's target. It can name a specific server -- e.g., the URL of my bank -- or it could name a generic service -- e.g., a URI that would be recognized by any "standard internet cache service" (if such existed). Like much of the SOAP framework, details are left to the application(s) involved.
SOAP defines two special actor (role) values, a "none" value means that the header is targeted not to any intermediaries, but rather to the ultimate destination. For example, a new ATM-like client could generate the following header, without having any idea of where the message is going:
<tns:AccountSubIdentifier
SOAP-ENV:role="http://www.w3.org/2002/06/soap-envelope/role/none">
1
</tns:AccountSubIdentifier>
Pages: 1, 2 |
