A Smoother Change to Version 2.0
"Ch-ch-ch-changes" sang David Bowie, "Just gonna have to be a different man. Time may change me but I can't trace time." It's a great idea for a song, but when moving to the next version of an XML-based exchange, we would like a transition with less stutter. However, this is not easy: on one hand, we want old version processors to accept new messages, the way older browsers can display newer HTML by ignoring unknown tags. On the other hand, those "mustIgnoreUnknown" semantics are often unwanted. In financial transactions, medical care, justice, etc., certain parts must always be understood -- we'd rather have a physician grab the phone and call us than have him ignore those parts about lethal allergies that his client software did not understand. SOAP provides a mechanism for SOAP headers: a "mustUnderstand" flag, which indicates which parts may not be ignored. Unfortunately, this mechanism is rather inflexible.
This article will outline a design pattern that makes a version transition much easier, and that is both more powerful and simpler than SOAP-style "mustUnderstand" semantics. In a nutshell, the next version of an XML vocabulary can be backward- or forward-compatible with the previous. We know the language version we use when we create a message, and all previous language versions that are forward-compatible with this message. So we put the list of those versions in the message. We cannot know which message versions the receiver supports, but if it supports only earlier versions, it can decide from the list whether it will process our message or not. If the receiver supports later versions, it can decide whether the message is backward-compatible with the receiver's version. In all cases, the receiver can make the best decision possible. Let's study this "Capability Compatibility Design Pattern" in more detail.
Figure 1. (In)compatible language
First, some background. Read David Orchard's "A Theory of Compatible Versions" or the W3C TAG's Versioning Finding for more. With traditional software -- say, a word processor -- things are simple: if your V2 word processor can read documents created with your V1 word processor, the V2 processor is backward-compatible with the V1 processor. If the V1 processor can read V2 documents, it is forward-compatible with V2. Of course no one will buy a V2 word processor, write documents, and then buy a V1 word processor and try to access the V2 documents, so this is uncommon in traditional software applications. It does happen when we email documents and the receiver has an older word processor than we do. It also happens a lot on the Web, where older web browsers may encounter markup that wasn't known when the browser was built. HTML tackles this problem by requiring software to ignore all unknown tags, and just display the content (if possible).
For two language versions -- L1 and L2 -- for message exchange, we can summarize:
- If L2 applications can read all L1 documents, L1 and L2 are backward-compatible
- If L1 applications accept all L2 documents, L1 and L2 are forward-compatible
Figure 2. Forward and backward compatibility