views:

67

answers:

2

I am designing a set of 'service' layer objects (data objects and interface definitions) for a WCF web service (that will be consumed by third party clients i.e. not in-house, so outside my direct control).

I know that I am not going to get the interface definition exactly right - and am wanting to prepare for the time when I know that I will have to introduce a breaking set of new data objects. However, the reality of the world I am in is that I will also need to run my first version simultaneously for quite a while.

The first version of my service will have URL of http://host/app/v1service.svc

and when the times comes by new version will live at http://host/app/v2service.svc

However, when it comes to the data objects and interfaces, I am toying with putting the 'major' version of the interface number into the actual namespace of the classes.

namespace Company.Product.V1
{
   [DataContract(Namespace = "company-product-v1")]
   public class Widget
   {
        [DataMember]
        string widgetName;
   }

   public interface IFunction
   {
       Widget GetWidgetData(int code);
   }
}

When the time comes for a fundamental change to the service, I will introduce some classes like

namespace Company.Product.V2
{
   [DataContract(Namespace = "company-product-v2")]
   public class Widget
   {
        [DataMember]
        int widgetCode;

        [DataMember]
        int widgetExpiry;
   }

   public interface IFunction
   {
       Widget GetWidgetData(int code);
   }
}

The advantages as I see it are that I will be able to have a single set of code serving both interface versions, sharing functionality where possible. This is because I will be able to reference both interface versions as a distinct set of C# objects. Similarly, clients may use both interface versions simultaneously, perhaps using V1.Widget in some legacy code whilst new bits move on to V2.Widget.

Can anyone tell why this is a stupid idea? I have a nagging feeling that this is a bit smelly..

notes: I am obviously not proposing every single new version of the service would be in a new namespace. Presumably I will do as many non-breaking interface changes as possible, but I know that I will hit a point where all the data modelling will probably need a significant rewrite.

I understand assembly versioning etc but I think this question is tangential to that type of versioning. But I could be wrong.

+1  A: 

Typically I have seen (and done myself) simply calling version 2 Widget2, IWidget2, etc. If you expect v2 to (probably) be the end-all, based on the lessons learned from seeing v1 in the wild, that is usually fine. But if you expect it to be more of a continually evolving thing, maybe think about a more fluid contract approach.

Rex M
+2  A: 

I've done it the way you've got (with V1, V2 namespaces and a Common namespace) and it's worked out fairly well. Basically, I have the actual code implemented in the Common namespace and each of the V1, V2, etc simply act as a wrapper around it.

In our case, the older versions typically stay around for quite some time. Usually, when a client requests access to our API we'll give them the "current" version at the time and then they'll just use that forever - unless there's a serious business case for moving to a newer version, then they pretty much never do.

Dean Harding