If there is one thing that makes your life 10-fold easier and doesn’t make developers’ lives a living hell, it is backwards compatibility.
The main idea in short terms:
Incoming traffic to your service is what your service’s logic depends on to work correctly.
There are 2 ways of how information can flow into your service:
1 - by receiving a request from another service;
2 - by receiving a response from another service.
By avoiding destructive changes in the parts of the contract that are responsible for inbound information flow, we allow our service to receive information in both structures: with the new changes and without.
It’s a tool for API contract migration: by holding back destructive changes for a certain amount of time, sprints or releases, we are allowing our services to move in production independently.
The result is a reduced amount of release communication needed for rollout or rollback.
This is the most elegant and simple explanation of backwards compatibility I’m able to condense.
By enforcing backwards compatibility, we are effectively breaking a dependency between different services, allowing different teams to deliver API changes at their own pace, while also creating a window of time when rollback can be performed without breaking an API contract (in case of major incidents).
You can enforce backwards-compatibility on all of your projects (backwards-compatibility by default), or you can apply it only to the most critical and interconnected projects. Creating what is effectively a release-candidate group.
You test projects from the same release-candidate group together and deploy them together. This way you can decrease the number of moving pieces in prod. Which may be good enough for your case.
At the same time, backwards compatibility by default is an important prerequisite to the left-shift deployment self-service, where the team leader of a certain service is responsible for this service delivery.
Pick your poison based on resources and company needs.
That’s it! You now know everything about backwards-compatibility.
Fin.
P.S.:
Yet, there still can be a question of why we should concentrate specifically on incoming traffic only.
Task: You need to make sure that you provide teams with simple-to-understand backwards compatibility rules.
Well, let’s look into all possible options of backwards-compatibility handling:
You can make teams responsible for doing all communication in backwards backward-compatible manner (incoming and outgoing).
Sounds great on paper; if you have a backwards-compatibility problem between 2 projects of your company, you will have 2 teams doing homework! And the possibility of an issue arising again is twice as likely!
Until you realize that: In situations when more than 1 team is responsible for something, nobody can be held accountable for the contract breach.
Also, it’s unnecessary overkill.The second way is to make teams responsible for doing only outgoing communication in a backwards-compatible.
Which is essentially delegating responsibility for our service's correct work to other teams’ shoulders.
”Our service failed because the other service did not do its homework”
This approach does not remove project dependency; it only shifts responsibility onto someone else.Teams care only about making their service work, no matter what changes are introduced. It’s simple to assign accountability for failure. And it will be fair.






