Using WSDL & Schema for Compatible Evolution

| | Comments (0)

Given that we want to be able to describe that an interface is compatible with another so that a client to decide when or if it uses new features, we can look at the tools that we have available for us.

Earlier, I posited a reservation interface with a findFlight and bookFlight operations. We can describe this using WSDL and Schema. Using a super duper shorthand, the interface might look something like:

<definition targetnamespace="reservation-ns">
<schema>
<type name="findFlightInput"/>
<type name="findFlightOutput"/>
<type name="bookFlightInput"/>
<type name="bookFlightOutput"/>
</schema>
<interface name="reserverationInterface">
<operation name="findFlight" input="findFlightInput" output="findFlightOutput"/>
<operation name="bookFlight" input="bookFlightInput" output="bookFlightOutput"/>
</interface>
</definition>

Using the definition of compatible evolution, we are going to restrict the changes to ensure compatibility. We are going to add an optional method, getFlightStatus, add an optional element to findFlightInput, and add an optional element to bookFlightOutput.

Now we are faced with some hard questions. How do these interfaces relate? Should the same targetnamespace and/or interface name be used?

WSDL 2.0 has a really cool new feature that allows an interface to extend another interface, by adding operations to the interface.

We *could* say that reservationInterfaceV2 extends reservationInterfaceV1. But what to change on the interface, the namespace name or the name? Let's just pick that the namespace of the interface changes, and not the name.

The definitions file would import the reservation-ns names and then make a {reservation-v2-ns}reservationInterface that extends {reservation-ns}reservationInterface.

But there's a hitch: We don't have way of specifying whether the additional operations are required or not. WSDL 2.0 does have a wsdl:required attribute to indicate whether extensions are mandatory or not, but this wouldn't be used on an interface operation.

What we need is some way of differentating whether an interface extension is compatible or not. Perhaps the simplest solution would be an "isCompatibleExtension" attribute on the extending interface.

Now how do we model the data format extensions? The first one, additional data on the findFlight input, seems the easiest. As I suggested before, the new schema should re-use the namespace name, the element name, and simply add in the optional element to the schema. It *is* the new format. This is why I've consistently advocated re-using namespace names and names when backwards compatible evolution is done, is to enable exactly this change.

As always it seems, there is a hitch. This means the first version of the interface must be mutable. We have to change the schema of the findFlightInput in the reservation-ns.

Many people have advocated that the extension should be done in a new namespace. But this has a real problem because the schema *can not* be updated with the optional extension *and* preserve extensibility. Any time somebody uses another namespace, it means that a schema cannot be written for the new structure. Which seems really bad to me. The whole point of writing schemas and metadata is to describe in a machine readable format and interoperable format the messaging requirements.

The last change, the addition of optional elements to the bookFlightOutput, is the hardest. The interface MUST have been written to follow a number of rules as I described in the xml versioning article: provide extensbility and follow must Ignore Unknowns. The receiver is going to get data that it has no idea about, and so it needs a way to handle it. The simplest approach is for it to ignore the data.

The schema that describes the extension to bookFlightOutput will need to follow some kind of mechanism to distinguish between the target namespace and other namespaces. I believe that putting these extensions in the target namespace allows us to write a schema for the extensions and retain extensibilty. As shown in the article, I used an Extensibility Element that contains the target namespace extension. It's not pretty, but it does enable us to write a V1 schema and a V2 schema that both validate the old and the new data. There are other variations on Extensibility that allow preservation of wildcards - the trick is to make sure that the determinism constraint of schema is accomodated. But the variations are a different story.

In summary, to make a reservation service V2 that is compatible with V1, the V2 author must:
- have a mechanism for asserting that the V2 operations extensions are compatible V1. This is not available in WSDL 2.0
- have a mechanism for revising the input schemas in a backwards compatible way. They can do this using XML Schema and using the same namespace name and names
- have a mechanism for revising the output schemas in a forwards compatible way. They can only do this by following some complex rules and schema design techniques. As I've said many a time, Schema does not have a way for "casting" or substituting an unknown type into a known type, so we have to layer that onto Schema.

If the constraints are not followed, they cannot claim that the new interface is compatible with the old interface.

I think it would be interesting and useful for WSDL to be able to describe that the V2 interface follows all the necessary constraints to be compatible with V1, and thus the client has the option about whether to use the new operations or data in V2.

Leave a comment

About this Entry

This page contains a single entry by Dave Orchard published on June 29, 2004 2:04 PM.

Scenarios for Interface Compatibility was the previous entry in this blog.

Atom 0.3 WSDL 2.0 is the next entry in this blog.

Find recent content on the main index or look in the archives to find all content.

Categories