June 10, 2003
As you may know by now, SOAP 1.2 has reached Proposed Recommendation (PR) status, which means that the XML Protocol Working Group believes that it's done. A few PR issues have been raised. It can be fun to look at the list, as the issues range from "I found a typ" to "this isn't full XML, send it back to the committee". If you're pedantically inclined -- and everyone in the computer field must have at least some inclination in that direction -- now is the time to break out the coffee and the reading glasses in order to find issues of your own.
Within the next week or two, we should know if Tim Berners-Lee approves the PR, making it a formal W3C Recommendation (i.e., a standard in everything but name); or, if he identifies issues that need to be resolved, requiring another round of work. The results could be interesting: there are, as usual, a number of political issues involved.
First, the WG is clearly done. It met the requirements, addressed the hundreds of issues filed, and wrote a set of documents that definitively and comprehensively defines a plausible evolution of SOAP 1.1. Second, there are several influential individuals who are adamantly opposed to the current Web Services framework and its SOAP underpinnings. For example, consider a Mark Baker's blog item, titled " Gauntlet Tossing" or Elliotte Rusty Harold's PR issue. Third, SOAP and SOAP 1.2 represent a significant corporate involvement, and it would be risky for the W3C to force that train to make a pit-stop. Last, most people like to feel that they're being told what to do, and they often get persnickety about it.
Infoset: Not the Root of All Evil
The biggest difference between SOAP 1.1 and SOAP 1.2 is that the 1.2 specification is built around the Infoset. Last November, I wrote a column about why this is bad. If only out of fairness, we should now look at why it's good.
The descriptions SOAP message processing are no longer based on syntax but on the information that the message carries. An implementor can determine what information items are important and must be preserved. It's now feasible to understand how to "tunnel" a SOAP message safely over any appropriate transport. Following the logic, you can know see that SOAP is now much more transport-neutral.
With any luck we'll see a wide variety of environments supporting SOAP messages in a very powerful way; as much as possible, they will look like native messages within the environment, but they'll be able to cross that environment and be safely converted to "classic HTTP/SOAP" without any information loss. In other words, I can have HTTP-based servers at each end of a processing pipeline, but have MQ, SMTP, CORBA/IIOP, or other intermediaries doing parts of the processing along the way.
If the middleware vendors follow through on that promise, we really will have a universal distributed messaging infrastructure. I'm actually fairly optimistic about this, since it seems the only way that proprietary middleware stands a chance of not being wiped out completely by HTTP plumbing and WS-xxx headers commoditizing their value-add for items like reliable transport.
The relationship between SOAP, MIME, and HTTP has been cleaned up. Most SOAP developers
will probably never notice this, but it's a good thing. IETF RFC 3023 defined a set of MIME media types
for XML and a "+xml" suffix convention for new types that are XML based but have special
processing requirements or implications. SOAP 1.1 used
text/xml, which meant that a browser (or server) couldn't distinguish between
an XML document and a SOAP message. SOAP 1.2 defines the
application/soap+xml media type. As part of this registration, the
SOAPAction header has become an "action" parameter in the MIME type.
Developers might notice this, and might find their situation improved, since it's
easier to get control over the MIME bits than the HTTP bits when they're developing
To summarize, while SOAP 1.1 would have these HTTP headers:
Content-Type: text/xml SOAPAction: "http://example.com/ticker"
A SOAP 1.2 message would have the following:
Content-Type: application/soap+_xml; action=http://example.com/ticker
Moving all of the metadata into the one place where it should be is also a good thing.
The true genius behind SOAP is the
SOAP:Header element. By requiring all
top-level elements in the header to be namespace qualified, the SOAP header provides
consistent place to put messaging metadata in a way that is guaranteed to not conflict.
SOAP survives into the next century, it's because the Federation will have defined
that handles tachyons and time-travel:
<tns:Ordering SOAP:mustUnderstand='true'> <tns:ReplyBeforeRequest value='never'/> </tns:Ordering>
More seriously, there are already over a dozen specifications that define SOAP header elements to provide message routing, transactional semantics, message security, and so on. This will undoubtedly continue, as vendors use this mechanism to provide their own special features, admittedly sometimes with the goal of locking-in customers to a specific implementation of this open standard.
SOAP 1.1 defined actors as intermediary processing agents that would perform actions
based on SOAP headers that were targeted to them according to the URI value of the
actor attribute. SOAP 1.2 cleans up this language by renaming the attribute
role, reinforcing the notion that the header is intended for a particular
type of processing. The improvement becomes obvious when you realize that a single
processor can function in multiple roles, but it's harder to think of the same processor
action as different actors.
SOAP 1.2 also defines two new roles. The first is none, which is used to specify a header that no intermediary should process, although they may need to examine the contents if another header directs them there. The second, ultimateReceiver, is used to explicitly mark a header as intended for the final recipient of the message. As with SOAP 1.1, this is the default if no role (actor) is specified.
SOAP 1.1 was somewhat ambiguous about header processing. For example, suppose the
arrived at its final destination, and it had headers with
that were targeted to actors that the final recipient didn't support? Some argued
was an error, since the proper intermediaries never saw the message, and that the
recipient should send a fault back. Others felt that the specification was vague,
processing could start before the application realized some headers were there, and
was too expensive to require a pre-scan. In addition, the header could be processed
reinserted by the actor.
SOAP 1.2 introduces the
relay attribute to make this explicit. If a processor
sees a header with a role that it supports, the
indicates whether unprocessed headers should be forwarded or stripped. This attribute,
particularly when used with mustUnderstand, allows a sender to assert fine-grain
control over all header processing. The semantics of mustUnderstand have not been
changed in SOAP 1.2, although the values have been changed from 0 and 1 to
true and false.
Arguably the most visible change to SOAP developers is that the format of a SOAP fault
changed dramatically. First, the client and server terms have been renamed to
the more-appropriate sender and receiver. The Java-style dot notation for
fault codes (e.g.,
Client.Authentication) have been replaced with XML qnames
and an initial set of fault codes are defined in the SOAP 1.2 namespace.
To get extensibility in faults analogous to the old dot notation, a
element is defined. For example, an authentication failure could include this fragment:
<SOAP:Code> <SOAP:Value>SOAP:Sender</SOAP:Value> <SOAP:Subcode> <SOAP:Value>saml:Unauthenticated</SOAP:Value> </SOAP:Subcode> </SOAP:Code>
New subelements allow multilingual text reasons to be provided and a placeholder for arbitrary XML details.
<SOAP:Reason> <SOAP:Text xml:lang="en-US">Invalid login</SOAP:Text> <SOAP:Text xml:lang="Igpay-Atinlay">Invaliday oginlay</SOAP:Text> </SOAP:Reason> </SOAP:Detail> <... arbitrary XML here ...> </SOAP:Detail>
More from Rich Salz
Hopefully SOAP endors will make it easy to generate and parse these new formats: having multilingual server error messages can be a big win, although knowing what language to output might require close integration with the transport layer.
From the developer's perspective, however, at least initially the major difference between SOAP 1.1 and SOAP 1.2 faults is that SOAP 1.2 does not use HTTP status code 500 (server error) to indicate a fault. As far as HTTP is concerned, a fault is a normal HTTP response message and is an accommodation to the principles of REST. It will have interesting implications for programmers who write their own SOAP stacks.
Finally, the most most important change of all: As explained in section 6 of the SOAP 1.2 Primer: "SOAP 1.2 will not spell out the acronym".