Microservice Versioning

Architecturemicroservicessoaversioning

What is the best practice to adapt for versioning in a Microservice Based Architecture, in terms of supporting multiple versioned deployment of the same service during runtime and how the consumers would be able to use different versions?
1) If we use Routing based Versioning as one of the approaches mentioned here
then I guess we would have the following drawbacks

  1. Internal Services have to go through Reverse Proxy for consumption.
  2. Consumers always have to be aware of the required versioning.

Is it a best practice to expose the version information to consumers?

In any case, as I feel, the following always applies:

  1. For MAJOR version change, the consumers have to be changed.
  2. For MINOR version change (backwards compatible), only the consumer(s) that requires the added functionality needs to change.
  3. For PATCH version change, it's optional and would probably be seamless for any consumers to make use of it.

What kind of Microservice versioning strategy can help us in enabling the above?

NOTE – Please feel free to let me know if this needs to be split in multiple questions.

Best Answer

I think it is safe to say that as of now it is not a solved problem. In a Microservice Architecture, each service should be loosely coupled. If when you change a producer, you have to hunt down consumers to change them too, then it indicates that you have a design flaw. The routing based versioning presented in the link seems to have much more than a "few drawbacks".

Should you version the entire service or just the api?

If you version the entire service, you will invariably open quite a can of worms. Imagine that you implemented the first version (v1) of a service A. Imagine now that after a while, a new version (v2) had to be implemented because of the business. What happens if a bug is discovered on the v2 of this service? The team should check that the same bug doesnt exist on v1 too. If it does, v1 should be corrected and redeployed too. Even if it is just copy and paste, both versions need to be retested and redeployed. And what if there was refactoring between versions and the way to fix v1 is diferent from the way to fix v2? And what if instead of 2 versions, there are 5 or 10? Someone funnier than me should make a "That scalated quickly" meme for this.

Just by scratching the surface of how much headache this option could give, we basically can already decide by versioning just the api. But basically if you version your service on the code level:

  1. The team just has to support one version of the service (bugs are just corrected once)
  2. Less cognitive drain on the team for not having to understand tons of different and potentially very distinct versions of the service
  3. Less resource consumption
  4. Garantee that everything is consistent between versions (if not a garantee, at least it is much more probable)

How the client communicate what version of the api they will consume?

For this answer, I will refer only to REST apis because its what i know enough to talk about. There are basically 4 ways of versioning the api (that i can think of):

  1. Versioning the URI: "http://host/serviceA/v3/whatever"
  2. Version in the Accept Header
  3. Version in Custom Header
  4. Version as parameter

This tutorial will explain each one of these with their drawbacks better than me, but basically anyone of these should do just fine =)

How (the f*****g hell) do I sustain inumerous service versions in the same code? (are you crazy???)

Your service per se is just one. What you should do is apply Adapter Design pattern, so as to exist different versions of ins and outs interacting with the business layer of your service. This way you just have some versions of some objects, with it being transparent to the core of the service. It is the same conclusion of the article mentioned in the question, and it even has a neat example to showcase it.

Related Topic