Microservices and Me (3 Part Series)
Your work's been done for days. You've tested it, the QA team has tested it. The product owners have tested it and everyone on board wants it to go from staging to production. There's just one problem - Someone else's code has been merged in and is causing issues. It's not even in the same part of the system as yours but it's now in your staging branch and it's too tied up with other code to responsibly cherry-pick the changes you want into a release.
So you're now stuck waiting for that code to be fixed and tested before you can ship your code. Sound familiar?
Going the microservices route means that you've divided up your codebase into smaller, separate modules. Each module is basically (as much as possible) a self-contained entity that can be deployed individually without having to worry too much about what is ready in other services.
In fact, it's a good idea to think of each service as their own little completely separate company! Just like when integrating with 3rd parties, they are free to make changes to their systems and deploy on their own schedule.
No more waiting for other parts of the system to be ready! Deploy your changes!
Well, not quite. Microservices still needs to communicate with each other and maybe the outside world. So if you're changing any of the public-facing aspects of your service, you will have to ensure that you version your calls properly and provide backwards compatibility so that the other parts of your system still works after deploying your service.
Also, your deployment may still be blocked if your service is dependent on new changes being deployed in a different service and that service is blocked!
You have to always remember that your service will have clients and also be a client to other services.
Unfortunately, microservices won't solve your interdependency woes but if you do a good job in identifying the bounded context of your service, most of your changes will be internal, which means that you absolutely can deploy whenever your service is ready.
Probably not. I just wanted to highlight that this is another benefit of using this architecture.
You could achieve something quite similar if you create environments for feature branches and have the business test on these environments before merging the new changes into staging or production. This, however, is not a trivial thing to set up.
An additional benefit of the separation of your codebase is the fact that you can now secure portions of your code from specific people. Maybe you don't want the junior developers touching the core logic of the system?
You can now achieve this by simply denying them access to that service's code.
Again, it's not the only way to solve this - You should have automated unit and integration tests to ensure this doesn't happen and branch policies with a code review done by at least 3 senior devs and the catholic pope for good measure - but in my experience, what should happen and what does happen are generally two very different things.
Some projects have no tests. Unit tests can miss things, integration tests may be slow and only get run once in a while. It's possible for even senior devs to miss things and the pope may just be too busy that day to attempt to exorcise your code (I've been asked to please stop calling the Vatican).
So just in the case of enforcing modularity because of making it impossible to directly reference code that you shouldn't, it also creates the opportunity to make it impossible for people to change parts of the system that they shouldn't.
Most people want to make things perfect. Sometimes we evaluate the complexity of an upcoming goal or a problem. So, the fear to not complete it perfectly or "wrong" (Yeah, who are judges? 🤔) stops us even from trying.