This is part 2 of a series. You can read part 1 and part 3 as well.
Alternative Approaches to Interface Versioning
Lublinsky wrote a great article about interface versioning a while back (see page 38 of this issue of Microsoft’s Architecture Journal). This describes the state-of-the-art thinking about interface versioning in the web services world. Essentially he recommends versioning each method in an interface separately. (Sounds a lot like Win32’s approach of adding …Ex to every function when the original behavior no longer sufficed…) This approach is based on the insight that many parts of an interface will be stable for long periods of time, and that the most common kind of change to an interface is an addition. By increasing the granularity of the versioning, incompatibilities are less likely to arise for spurious reasons. This solves the classic problem where a .wsdl describes a dozen classes, a client uses only the first three, and yet the client breaks when something in the fourth class changes. However, it proliferates .wsdls and points of presence.
Another important discussion of this issue is “A SOA Versioning Covenant”, by Rocky Lhotka. This is an excellent review of the problem. (Note that the Lublinsky article, which is newer, discusses the covenant idea briefly.) Essentially Lhotka recommends that all objects accept messages (parameter lists to functions, recast as documents or self-contained packages of information); since each logical function will always have the signature
DoSomething(message), the need to version interfaces goes away as long as changes just involve new message types. Instead, the messages are versioned using schema capabilities. Lhotka further recommends changing from contract-oriented thinking (X is required) to a covenant (If you do X, I will do Y). This approach has some of the same benefits as the invention, but it still relies on versioning a full interface rather than the subset someone wishes to use, and the difficulty of managing versions of messages is ignored.
Although both of these treatments (and the sources they cite in their own reviews of the problem) are nifty, they leave me unsatisfied. The bottom line is that I want to evolve interfaces whenever it makes sense, without worrying about breaking people — and I also want people who use my interface to be able to do so with confidence.
Tune in to part 3 of this series for my proposed solution.
3 thoughts on “Decoupling Interfaces as Versions Evolve, Part 2”
Such a timely post. I am right in the middle of moving a distributed system from a custom RPC style communication to a messaging system. My current thought is to at least use the document mechanism to at least allow some compatibility among components running different versions. I am looking forward to part 3.
Synchronicity! I just wrote my first RabbitMQ client last week. Great minds think alike! :-)