SYSK 266: SOA Versioning Best Practices and on the Importance of Using Nullable Types and IExtensibleDataObject Interface in Data Contracts

“Interfaces are immutable…”Yes, we’ve heard that for years...The reality, however, is that contracts, both -- service and data, do change as more requirements are discovered, etc.Moreover, it’s not reasonable to expect that all clients of your V1 service will migrate to V2 service at the same time; so, you need to be able to release a new version without breaking old clients.

The rule of thumb is simple: if it’s a new data member on a data type (i.e. data contract) and it’s not a required element or it’s a new method (operation) on a service type and it’s not a callback interface, then you can add it to same class; otherwise, the versioning best practices recommend that you create a new data type in a new versioned namespace (versioned namespace allows you to keep the class name the same).

Here are some “good practices” I follow:

Use versioned namespace, e.g.

namespace YourCompany.Services.V1

{

[ServiceContract(Namespace="urn:yourcompany-com:v1")]

public interface ISomeService

{

}

}

When adding a new data member, use Order named parameter on the DataMember attribute

Add new data members at the end of the list

When using DataContract serializer, use nullable types so you can detect those situations when V1 client called V2 service and didn’t pass required data.Missing data elements will be mapped to nulls and you can assign default values in OnDeserialized event

If it’s a breaking change, e.g. a required data member is added, a signature of an existing method has to be changed, etc., then create a new type under next version namespace (e.g. YourCompany.Services.V2)