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开发者_JAVA百科, 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.
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.
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.
精彩评论