You’ll find plenty of tutorials online telling you how to rewrite a legacy codebase, plenty of developers telling you to rewrite your backend services to use Go, but I’d like to share my rewrite story to open your eyes as to what you are undertaking before you start. Then if you’re still set on refactoring, I’ll give you some recommendations for how to approach it.
My experience has been refactoring a legacy PHP web application. Almost four years ago I created a brand new Laravel (PHP MVC Framework) repo, and ~700 commits later, the two applications are still running in parallel on production.
The Great Divide
A typical rewrite approach is to find a way to run the new and legacy apps in parallel, and essentially use the new codebase for the re-written modules and fall back to the legacy codebase for everything else. Sounds quite straight forward but this split will cause the following:
- A more complex production setup, in my case Nginx proxying through to a different backend
- A more complex local development setup, ideally you will be mirroring your production setup locally. I ended up writing custom drivers for a tool I use to run website locally to replicate the new production setup.
Lack of new features for existing users
While you are spending development hours re-writing existing functionality, your users will not receive new features. You may be thinking, “but once the re-write is complete, new features will be easy to add” and you would almost certainly be correct. However, adding new features while the rewrite is in progress will be more difficult than if you hadn’t re-written in the first place. You will be working on an inherently more complex system, one that is split in two.
This depends hugely on the rewrite that you are performing, but in my case the rewrite meant going from no framework to a framework. This added a lot of bulk to each request and increased the response time by an order of magnitude.
You may/will introduce bugs
Systems which are live get more stable with time, and you are about to rock the boat. When you re-write the code, you will introduce regressions. Hopefully not too many, and tests will help you catch these.
Hopefully you haven’t found the aforementioned points too daunting, the decision to re-write should not be taken lightly and if it’s the right choice for your project, brilliant 🎉. There are a lot of benefits to rewriting, and to help you on your way, I offer you the following recommendations:
- Stick to the same programming language, hopefully some parts of your legacy codebase can be re-used, and sticking with the same language makes code re-use straight forward
- Tests — If you can write tests around your existing application, do. If you have existing tests written around functionality, use them to make sure you don’t introduce regressions. If you don’t have tests, and perhaps even if you do, take a look at the git history for relevant files (git log -p src/someFile.php), to see your bug fixes over time.
- Break the existing application down into modules, look for dependencies and clear divides to find your first module to rewrite. In my case, the application had a set of scripts which ran on a schedule (backups, notifications, etc), this was a clear candidate for rewriting first
I’ve learned a lot through this re-writing process and am considering writing a follow up article, do comment if you’d like to hear about it.