In the last week I had fun extracting out some smaller applications from a giant monolith. During the process I learnt, in the hard way, some lessons I think are worth sharing.
I’m not going to lie to you, it’s going to be hard. Much harder than you expected when you decided to do it. But it’s also going to be totally worth it. Just make sure you get all of your stubborness and get ready to smash all the brick walls you’ll run into. You’are probably going to hit many of them.
I’d start the process of extracting a standalone application by creating a new solution and move the code of the projects to the new solution. Don’t move the dependencies just yet, hit compile and have a look at all the errors the compiler is spitting out. It’s going to be a very sorry output, but don’t panic. At least you know where you should start looking at. The code with errors should fall in one of the following categories, from the most to the least desirable:
- you don’t really need that functionality anymore;
- the code has a dependency unrelated to the monolith;
- the code has a dependency on the monolith but you can refactor it;
- the code really needs to depend on some code in the monolith.
You’ll be surprised by the amount of cruft you’ll find. The good news is that if you don’t need a functionality anymore you can just delete all the related code and call it a day. This is by far the best situation you can be in while splitting out code from a monolith.
If you encounter an external dependency your best bet is to add it and keep going. It’s not going to cause you much pain and it’s not the case to put too much effor in cutting it. If you think the dependency should not be there leave it for now and put an item in your backlog. At this stage you still have most of your code broken so it’s not feasible to do this refactoring now.
Dependencies on the monolith
Depending on how modular your monolith is you might have few or many of them. If it’s possible, the best strategy to deal with these dependencies is to refactor the code such that it doesn’t depend on the monolith anymore. Unfortunately most of the time it is not possible so you need to move some more code out of the monolith to a library so you can treat it as an external dependency. Beware that this could be a very painful process that can bring you in very deep rabbit holes but there isn’t much you can do to go around it.
After many iterations you will have a smaller monolith and the application you’re extracting both depending on the libraries you extracted. These libraries might need some love, but leave it for another time. Now your goal is to get everything back in a working state.
Does your infrastructore support multiple applications?
Once everything is working you might still have some work that needs to be done.
If you don’t have multiple applications I’m afraid that you’ll find some bad surprises. All your infrastructre is likely to have the assumptions that there is only an application with a gazillon of entry-points. This means that you need to revise all the scripts and make them support multiple applications.
Once your scripts support multiple applications you are very close to finally let your application declare independence from the monolith. You probably just need to setup a few more plans in your continuos integration server. Wait for all of them to go green and celebrate.