I have a pet theory that refactoring is more difficult in a polyglot microservice world and that accumulating technical debt as a competitive strategy is more dangerous than it has been or once was. I hope to flush out this idea with a list of particulars. Specifically, what makes refactoring hard and how do we accommodate?
When old code has been written in a different language or framework that currently in use the rot accelerates as teams fear touching it.
Lack of familiarity with the codebase due to turnover or reorganization makes any modification scary.
Teams are doing less refactoring as they go and hoping they’ll get to do it later after deadline, but then the next big thing that needs to ship happens.
Refactoring is easier in microservices, it just requires certain things to be true and some discipline around rolling it out. Microservices allow you to change things in one place at a time.
You want to change what kind of data gets passed into a service? great, add an endpoint that takes the new data structure and dark-launch it in the receiving service. You can then take your time switching the producing side, rolling it out slowly, double writing for a while, etc.
Things like protobuffers externally define data structures that define interfaces between services. In the long term the workflow forces you to be more explicit about this thinking.
Polyglot microservice refactors can be harder because of the multivariate or multivector nature of them. The number of languages being one vector and the number of microservices being another vector. In a monolith there is no vectorization.
Single language, shared ecosystem micorservices has gone very well with challenging improvements in a day because every service used the same config library that they modified to pull values out of a repository. Yes, toil, but not risky, error prone work.
With all services in a monorepo changes to shared data structures could be done in one combo pull request. However, with explicit separation there is procedural value in being forced to introduce the change into different repos more deliberately.
One is more likely to delete code in a service oriented infrastructure because one can just shut down a service entirely rather than doing some advanced refactoring maneuvers to try and identify which code and tests can be dumped.
Externalizing data structures helps refactoring and more importantly deploying refactors safely to production.