@AgileSteveSmith hah! It would probably say “Don’t, or try not to”. Although it varies by what you’re versioning.
— ~/developers/chris (@ChrisAnnODell) April 30, 2014
Versioning is hard, so why do we do it? To enable consuming apps to resist change.
What if these apps were built to be tolerant of change? What if you built your API or library in such a way that you avoided breaking the contract, but added to it? What if you constantly push changes and consumers constantly consume them?
What would you need versioning for now?
“We do versioning to enable consuming apps to resist change” is a killer quote. There are also some really thought-provoking questions here:
1) How do you reach a world in which versioning is deemed wasteful? What alternatives are put in place (e.g. small batch size, monitoring, traceability, culture)
2) How can you build apps to be tolerant of change? Consumer Driven Contracts are one method that is very powerful
3) What do you do when a breaking change is unavoidable (it will still happen from time to time)
4) When do you want to use versioning to your advantage if you are the consumer (e.g. defer untrustworthy provider integration)
5) When do you want to use versioning to your advantage if you are the provider (e.g. force upgrade)
6) Why do organisations resort to complex versioning schemes (e.g. semantic versioning?) – to control impact of large batch
I think versioning should be used to communicate change, but too often it is used to control change due to overly-large batch sizes on both the consumer side and the provider side.
It would be great if you could expand on the above! At some point I'll add to this properly.
Thanks for your comment Steve and I apologise for taking so long to reply.
My experiences are limited to the world of the Web and in particular Web APIs. In this world we have greater control as providers of interfaces and increased flexibility when it comes to deployment. I have limited experience in worlds where apps are provided to clients and as such an upgrade process being needed. I can imagine that in such world there are far more barriers to change and even a desire for systems to remain the same.
1) I would encourage small batch sizes to allow for the changes that a client must handle to also remain small. The downside of this is being mindful of the rate of change and expectations on clients to 'keep up'. Monitoring is essential and an entire topic of it's own. With monitoring it's advantageous to track which clients are using a particular feature and to start any conversations around a forthcoming change as soon as possible. You can then monitor the usage as clients move away from it. This requires an understanding culture in the clients themselves.
2) I hadn't previously heard of Consumer Driven Contracts and a Google search led me to your own post on the subject (http://www.alwaysagileconsulting.com/application-pattern-consumer-driven-contracts/). The services I've worked on use HTTP as a communication mechanism and XML/JSON as the responses. The format of these responses is a contract between the provider and consumer. As long as nothing is removed from these contracts then updates can happen independently of each other. Note that these contracts allow for additions and this is where the flexibility lies – change is additive.
3) Breaking changes do happen, and in my experience there are multiple tactics that can be employed to allow clients to integrate the change without resorting to versioning. If you wish to remove functionality then it is a case of informing clients and monitoring the usage of the functionality as it decreases. Sometimes clients need more help and a bit of time to adjust to make the changes, but this is time not spent maintaining separate versions. Adding functionality should be simple as it should be ignored by any client not needing it.
4, 5 & 6) This is where my experience fails me as I don't fully understand the questions. I've never worked on providing a component, such as a framework or similar which would be built into a consuming app. I would assume that points 4 and 5 feed into the creation of versioning schemas such as Semantic Versioning which you mention in point 6. My understanding of Semantic version is to convey the intent of changes to a component and allow for clients to choose their own risk level, e.g. advertising a minor framework change and a client comfortable with accepting all minor framework updates whilst another client may be only comfortable with accepting patch level updates.
I highly recommend using HTTP as a communication method between clients and services, using an explicit and human readable response format as a contract (XML/JSON) and keeping your services tiny and focussed around a particular domain.
You could even call them MicroServices if you want to get all trendy 😉