Versioning Services

1,055 views
Skip to first unread message

Andy McGoldrick

unread,
Feb 14, 2011, 11:11:25 AM2/14/11
to servic...@googlegroups.com
Hi,

does anyone have any experience or good advice around a naming scheme for services so that changes to the interfaces could be handled nicely?

I was thinking about some sort of scheme where the urls begun with a date or version number so that with each breaking release, I could maintain backward compatibility, by adding a new url branch but wondered what other people do to address this.


Thanks

Andy

mythz

unread,
Feb 15, 2011, 8:26:23 AM2/15/11
to servic...@googlegroups.com
Hi Andy,

Sorry for the late reply, I've been busy getting the v1.82 of ServiceStack in a releasable state!

For versioning, you are going to be in for a world of hurt if you try to maintain different end points. I started doing this at mflow but as soon as you support your first version the development effort to maintain multiple versions of the same service explodes as you will now need to maintain the mapping of different types.

My recommendation is not to explicitly version but take advantage of the versioning capabilities inside the serialization formats. 
With XML DataContract's you can freely add and remove fields without making a breaking change. If you add IExtensibleDataObject to your response DTO's you also have a potential to access data that's not defined on the DTO. So my approach to versioning is to program defensively so not to introduce a breaking change, you can verify this is the case with Integration tests using old DTOs. Here are some tips I follow:

  • Never change the type of an existing property - If you need it to be a different type add another property and use the old/existing one to determine the version
  • I maintain an explicit 'int Version {get;set;}' in the Request DTO constructor so its implicitly always set. I use an integer for the version starting at 100
  • Keep a single global namespace 
    • I do this by using the assembly attribute in your projects AssemblyInfo.cs [assembly: ContractNamespace("http://schemas.servicestack.net/types", ClrNamespace = "MyServiceModel.DtoTypes")]
  • Program defensively realize what properties don't exist with older clients so don't make them mandatory
I'm sure I use other strategies but that's all I can think of at the moment.

Note: you generally don't need to worry about versioning with JSON clients as the versioning capabilities of the JSON and JSV Serializers are much more resilient as can be seen here.

Hope this helps!

Cheers,
Demis

Andy McGoldrick

unread,
Feb 15, 2011, 9:30:53 AM2/15/11
to servic...@googlegroups.com
Hi Demis,

that is great advice and just the sort of thing I was looking for, I will take these suggestions in to account when carrying out further design/planning.

Also, the new HTML5 Report format is great, looks really great and easily convey the structure and content of the data.

Cheers

Andy

Demis Bellot

unread,
Feb 15, 2011, 9:35:13 AM2/15/11
to servic...@googlegroups.com
Thx! the HTML5 Report was a good weekend effort that I think will provide a lot of value - as I'm now use it all the time myself :)
I think I should be able to make some enhancements via simple customizations that should also be useful, check the next release for features in this area!

Yep, I've found that by following a defensive development style I can by-pass the need for strong-typed versions of services.

Cheers,
Demis

jakescott

unread,
Feb 15, 2011, 9:45:37 AM2/15/11
to servic...@googlegroups.com
Hi Demis just a couple questions :)

Why do you need to keep a single global namespace?
Also what does maintaining a version number in the RequestDTO help you with?

Demis Bellot

unread,
Feb 15, 2011, 9:52:33 AM2/15/11
to servic...@googlegroups.com
Short answer is because XML Namespaces are the root of all evil :)

Longer answer, an xml document composed of multiple namespaces exploding the size of the payload. Also any change to the namespace is effectively a breaking change, for all the problems it causes it provides no added value which is why I try to avoid it at all costs.

Also what does maintaining a version number in the RequestDTO help you with?

If you're using a C# client with an older assembly, the code:

client.Get<MyServiceResponse>(new MyService { Id =1 }); //will explicitly set MyService.Version = 100;

so clients with a newer assmbly with the same code, i.e:
client.Get<MyServiceResponse>(new MyService { Id =1 }); //will explicitly set MyService.Version = 101;

so it allows you to be able to detect the version of DTOs that was sent without adding additional boilerplate/ceremony to your C# clients

Hope it clears things up,

Cheers,

jakescott

unread,
Feb 16, 2011, 7:13:24 AM2/16/11
to servic...@googlegroups.com
Just talked to my new CTO and hes been using CentOS for a while and is really keen on using Mono (And has used Mono is the past!)

Pretty excited to start using ServiceStack and Mono :)

Demis Bellot

unread,
Feb 16, 2011, 7:20:24 AM2/16/11
to servic...@googlegroups.com, jakescott
That's awesome news Jake! 

I'm sure between myself and the MONO crew any issues that may come up should be swiftly resolved!


On Wed, Feb 16, 2011 at 12:13 PM, jakescott <jake.net@gmail.com> wrote:
Just talked to my new CTO and hes been using CentOS for a while and is really keen on using Mono (And has used Mono is the past!)

Pretty excited to start using ServiceStack and Mono :)



Demis Bellot

unread,
Feb 16, 2011, 7:23:56 AM2/16/11
to servic...@googlegroups.com, jakescott
Although, having said that I think for the best support from the MONO team you should maybe look at using OpenSuse/Suse, since its developed and supported by Novell/(or whoever owns them now). 

At the same time CentOS should be a safe option as that's what I deploy to currently. The difference might be in the level of support you receive from the MONO crew.

jakescott

unread,
Feb 16, 2011, 8:15:43 AM2/16/11
to servic...@googlegroups.com, jakescott
Yeah I just want to go down the path of least friction so whatever is the simplest to get up and running on will be sweet. The other option still is using AppHarbor which would make doing deploy's super fun again. Also I wanna have a play around with app harbor and bounce
https://github.com/refractalize/bounce to see how that would work.

It would be interesting to know a bit more about how you did your build a deploy stuff for sites like mflow (All in good time of course)

Demis Bellot

unread,
Feb 16, 2011, 8:34:40 AM2/16/11
to servic...@googlegroups.com
Hi Jake,

Well I found out from Dale (@dwragan) has been working to get ServiceStack running on Moncai.
It might be the better choice since Monca's primary deployment target is MONO on Linux, and as he is accessible on IRC (#moncai, #owin) and is actively supporting linux it might be the better story. If you want I can ask him to get you a free beta account so we support you better?

It would be interesting to know a bit more about how you did your build a deploy stuff for sites like mflow (All in good time of course)

Yeah that's something else I should've documented already :)

Basically to deploy to linux I just do a 'git pull git://github.com/ServiceStack/ServiceStack.Examples.git' and ftp the bin/ folders built on VS.NET to their respective Web Host folder. So I don't actually any of the MONO build chain at all.

Note: I think Apache + mod_mono is the recommended option so I would probably go with that since that's where more of MONOs development effort goes into supporting and Mono FastCGI is pending a re-write. In the near future I will look at converting to Nginx >  reverse proxying to Apache + mod_mono and post the instructions on a wiki.

In the meantime for http://servicestack.net I currently use with Nginx/FastCGI, and just followed the instructions detailed here:

Note: as of fastcgi-mono-server2 also includes fastcgi-mono-server4 which I believe is now the recommended option.

I use the --appconfigdir directive (see: fastcgi-mono-server4 /?) and specify the definition of all my projects in a separate config file, here is the command line option I use:

/opt/mono/bin/fastcgi-mono-server4 --appconfigdir /etc/rc.d/init.d/mono-fastcgi /socket=tcp:127.0.0.1:9000 /logfile=/var/log/mono/fastcgi.log

ServiceStack.webapp:
<apps>
<web-application>
        <name>ServiceStack.Northwind</name>
        <vhost>*</vhost>
        <vport>80</vport>
        <vpath>/ServiceStack.Northwind</vpath>
        <path>/home/mythz/src/ServiceStack.Examples/src/ServiceStack.Northwind/ServiceStack.Northwind</path>
</web-application>
</apps>

And here is an example of my mapping in nginx.conf:

        location ~ /(ServiceStack|RemoteInfo|RedisWebServices|RedisAdminUI|RedisStackOverflow|RestFiles)\.* {  
                root /usr/share/nginx/mono/servicestack.net/;  
                index index.html index.htm index.aspx default.htm Default.htm default.aspx Default.aspx Default.ashx;  
                fastcgi_index /default.htm;
                fastcgi_pass 127.0.0.1:9000;  
                fastcgi_param SCRIPT_FILENAME /usr/share/nginx/mono/servicestack.net$fastcgi_script_name;  
                include /etc/nginx/fastcgi_params;  
        }

Hope this is helpful!

- Demis

jakescott

unread,
Feb 16, 2011, 9:13:44 AM2/16/11
to servic...@googlegroups.com
Thats awesome news that Dale is working on getting Service Stack running in Moncai! I've been following him for a while too building out Ottoman for CouchDB.

I will no doubt be setting up some linux boxes and having a play around with stuff hopefully pretty soon so I am sure this info will come in handy :)

mythz

unread,
Sep 13, 2012, 4:23:15 PM9/13/12
to servic...@googlegroups.com
Note: I've expanded my answer with my current thoughts here:
Reply all
Reply to author
Forward
0 new messages