When developing a server infrastructure using micro services, there are a lot of opportunities to repeat the same pieces of code among many of them. So one of my developers likes to put stuff in a helper library, shared between all micro services. We all know the golden DRY principe: Don’t Repeat Yourself.
Here’s a little story of adding unnecessary coupling between micro-services:
- I add
createServer()to my helper lib, because it’s the same on all my services.
- I later add to helper lib that
API_SECRET_KEYenvironment should be present when doing
createServer(). All my services needs that.
- Oh, I forgot, there’s this module X that don’t have any private API so don’t require any
API_SECRET_KEY. Next time we update the helper lib on this modules, it wouldn’t start!
- No problem, the developer change
createServer(), adding a parameter that defines if
API_SECRET_KEYis required or not. Problem solved. Or is it?
- Later, someone upgrade the helper lib from another module Y, which doesn’t specify this new parameter to
isSecretRequired = undefinedis similar to
isSecretRequired = false, so
API_SECRET_KEYenforcement got silently broken in module Y, until someone notices… Hopefully not to late.
This is an imaginary scenario just to illustrate that adding interdependencies between micro-services breaks one of their may advantages: isolation.
… and isolation removes complexity.
I know it’s against the DRY principle, but for larger projects there are good cases where repeating yourself makes stuff simpler to manage in the long run.
To completely remove the opportunities to break service X while doing changes to service Y: Don’t Share Code.