XML.com: XML From the Inside Out
oreilly.comSafari Bookshelf.Conferences.

advertisement

Processing SOAP Headers

Processing SOAP Headers

July 17, 2002

Last month we built a simple client for the Google API. In this month's column we'll look at how SOAP headers can be used to talk to an intermediate server that adds value to the basic search service. The value-add is actually pretty silly: we'll send the query, pick one of the results at random to return, and send it back as an HTML page in Pig Latin. Our goal, however, is to understand how to process SOAP headers, and why you'd want to do so. But first I want to thank Google for providing a wonderful Web API, which it is, module the concerns I addressed in my first column.

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.

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

Next Pagearrow