SOA/MSA Backward Compatibility

One of the real game changing benefits of SOA / MSA(Microservices Architecture) is flexibility. Flexibility give you power todo things as you wish, in order to have flexibility you need have decoupled things but hold on a second, in a service oriented world everything is done via a contract and services are coupled to this contracts.

How could you still have flexibility if the contract changes you need rebuild all consumers and deal with the changes? Even worst than that - whats makes SOA different from webservices or procedures calls on the data base? (remember soa/msa is not about technology is about principles and design/arch.)

Service Contracts

Contracts are flat objects, in the end of the day is just data + other aspects around the service, like behavior, protocols, etc... Lets say you define the right contract, your business will change and that fine, but that change will affect other services or consumers? Maybe maybe not, but if you keep breaking your consumers you have a problem you will need coordination.

Coordination is bad because will kill you. You will endup with branches and releases that are tight and coupling, coupling is the root of all evil. Ultimately you want have different release cycles or even better you want have continuous delivery - speed is archive if you have isolation of each component - so we need independence - but how we got that independence?

Contract version

So you need explicit version you contract and start making differentiation around changes. You will have breaking changes and non-breaking changes. So what is a non-breaking change? Is something it not require the consumers to change they code - in other words is optional it wont break they code or logic.

So lets say you have a interface or a trait that represents the service, you will have classes for the input and output parameters, all that is part of the contract so you need to version this objects. The easiest thing todo is version the package or namespace.

For changes that will break the consumers, things like: add a required parameter, remove a output field or include an mandatory field or rename something you will break the consumers than you should create a new version. With this new version you can add you changes but you would still keep the old contract version.

Note on Deploy and Physical Architecture: Some folks use to have different services instance, thats leads to braching hell - IMHO is better have just one version of the service implementation and deal with the changes(backward compatibility) by code.

Multiples Contract Versions - Same Code

Thats the right thing todo if you want have flexibility with less complexity - CODE is better than branches. You will end up having to say explicit SOA/MSA Governance policies like: How many contract versions should we keep at he same time? 3,5,10? depends of your needs and how much you want to spent on backward compatibility.

This is one of the most important things around services. This is what makes possible to have localized changes. Now a dayz around microservices we are talking alot about isolation in sense of database, hardware and software, but if you dont have this kinda of mechanisms on the contract side of services you wont have the flexibility in sense of development and fast deploys and release oft

Service Internals - Dealing with BC

No matter what kind of architecture of design your service have it, you will need deal with backward compatibility.  The easy thing todo is keep the service implementation on the latest version and them migrate the old contract requests - responses to the current code.

So you would have an BC layer where you apply most of changes - most of times you be just a set of copy and past changes here and there, however sometimes this would not be enought so you might need have BC converters close to the service internal domain thats fine as long as you make that explicit maybe tought some interfaces/traits because this is a temporary code.

The nice thing about this is you can re-deploy just the implementation later and when every consumer migrated to the last version you can delete the old contract and code.

Popular posts from this blog

Kafka Streams with Java 15

Rust and Java Interoperability

HMAC in Java