Friday, August 06, 2010

WCF Best Practices–Versioning

Operations

Adding new operations is a non-breaking change.

Removing an operation is a breaking change.

Adding, changing or removing a parameter for an operation is a breaking change.

Extending contracts: A good practice is to use inheritance on your interface to extend it and add new operations. You setup the service to use the new inherited interface. This allows old clients to continue using the service and new clients to use operations available in the inherited interface.

Data-Contracts

The schema WCF produces for data contract types makes no provisions for versioning.

It is generally a good idea to consider your data-contracts as immutable once they are published.

Though, adding a new member to the data-contract is considered a non-breaking change.

Removing a member from the data-contract is considered a breaking change only if strict schema validation is desired. (This is the recommended way of looking at data-contracts)

Changing the type or name is considered a breaking change.

Changing the name or namespace of a data-contract is a breaking change.

Changing the IsRequired field from false to true is a breaking change.

Enumerations

Adding or removing an enumeration member is considered a breaking change.

Changing the name of an enumeration member is breaking change (unless you use the “EnumMemberAtttribute” attribute).

Data-Contract Equivalence

For data contracts to be equivalent, they must have the same namespace and name. Additionally, each data member on one side must have an equivalent data member on the other side. In addition, data members must have the same name on both side and they must represent the same type of data (data contracts must be equivalent).

 

 

Other best practices:

Specify {Name, Namespace, and Action}

By default, the name of a service contract is the name of the interface. The default namespace is http://tempuri.org and each operation’s action is "http://tempuri.org/contractname/methodname".

The best practice is to explicitly specify the name, the namespace for the service contract, and the action for each operation. (This avoids using "http://tempuri.org" and prevent interface and method names from being exposed in the service’s contract).

[DataContract(Name = "MyData",
Namespace = “http://www.aggregatedIntelligence.com/WCF/2010/06/MyService”)]
public class MyDataClass
{ [DataMember(Name=”FirstName”)] public string FirstName{...} }

The above definition will allow you to change the name of the class or the FirstName property and not cause any issues to client consumers as the Name and DataMember have been fixed by the attributes.

References:
Service Versioning: http://msdn.microsoft.com/en-us/library/ms731060.aspx
Data-Contract Versioning: http://msdn.microsoft.com/en-us/library/ms731138.aspx
Data-Contract Equivalence: http://msdn.microsoft.com/en-us/library/ms734767.aspx
Best Practices – Data Contract Versioning: http://msdn.microsoft.com/en-us/library/ms733832.aspx
Data-Contract Names: http://msdn.microsoft.com/en-us/library/ms731045.aspx
Types supported by the DataContractSerializer: http://msdn.microsoft.com/en-us/library/ms731923.aspx
Collection types in Data Contracts: http://msdn.microsoft.com/en-us/library/aa347850.aspx

No comments: