There seems to be an on-going philosophical debate about exactly how to version a REST web service. For me though, the number one issue is practical question regarding how easy/hard is it to implement and maintain in a Java servlet based backend. My company is building a new REST web service and while we are not currently concerned with versioning it at this time, I do not want to make an architectural decision that would paint us into a corner.
I guess the primary decision we have to make right now is should we put the version identifier in our URI or in the media type (or both). In case its relevant, we will mint only a few new media types. Also the application has 50+ resource URIs.
What are the pros and cons of each approach relative to implementing them in our Java servlet?
My initial thoughts:
1) I like the idea of versioning the media types (e.g. "application/vnd.mystuff+xml;version=1.0"), because it feels the same as versioning the XML schema for a SOAP/RPC web service. Also, it seems like conneg was designed just for this sort of thing. However, It seems like implementing this would be difficult if not impossible because our application is created with domain driven design principals and we can't just create new versions Java classes and have them sit along side the old ones. So we'd have to implement the new Java classes and then hand code JSON/XML serialization/deserialization to support all the old versions of media types. I guess this is no different than versioning XML Schema for SOAP...
2) On the other hand, if we were to version the URI's (e.g. "http://ourapp.com/v1/mystuff"), then our customers could deploy two entire versions of the system and stand them up as two separate servlets with different context mappings. However, we'd have modify the JPA (ORM) mappings of the v1 Java classes to use the v2 RDBMS schema. This may not always be simple, but I can easily understand how it could be done. This approach bugs me however because "application/vnd.mystuff+xml" will return two different XML models corresponding to two different XML schemas. But maybe it doesn't matter as the client knows what it asked for because it used the v1 or v2 URI...
Or is there an easier to implement, alternate approach we are not considering? Or is it ok to punt on this entire issue and worry about it later?
If the restful services are used by mobile applications then it would a bit difficult to bake in the processing of both responses. In my opinion keeping the version in the URL is the better way as this would be easier to decommission the old endpoints when convenient.