Tuesday, 25 May 2021

Fighting your framework: don't do it

New role, new opportunities. This time I'm off Python, or at least not being the main development language, and into Java. But starting to see the same patterns emerge.

My new job involves using Java, specifically, Spring Boot. You may have a lot of arguments against Spring in general, and I'd agree with most of them. However, it is hard to find another framework with such extensive coverage on a number of very essential topics. From relational to unstructured data access, MVC, security, testing... all in one of the fastests (only second to compiled ones) and more popular languages out there that has also a dazzling number of libraries available covering almost anything else not covered by Spring itself. What? You say bloated? Yes, gimme bloat if I can spin up a basic app in a couple of hours. You say complex? Yes, it is, so much that a side project (Spring Boot) was born to simplify the management of dependencies and generally avoid your head exploding.

In a sense, this is not different from Django: you may have a lot of valid points against using it for production applications, but it does have a lot very powerful counterpoints that completely justify its adoption: insanely fast development cycle, a test runner that lets you use actual databases to do actual testing without taking 20 seconds to set up the testing harness (I wish Spring had something like that), a load of libraries and projects you plug an start using in seconds...

So yes, if you're starting an app from scratch these day, you better have very, very good reasons to not use Spring (if you want Java) or Django (if you prefer Python) 

And one of the most interesting parts when joining an existing development team is that you get the chance to understand architectural and layout choices made at the time the app was created and evaluate how these decisions have contributed to the evolution of the app. Or instead have became obstacles for developing new functionality.

I'm starting to notice a pattern that invariably comes true: the decision to "fight" the framework and solve a problem by trying to replace some of its built in functionality is one of the biggest blockers to evolve an app. Invariably, the custom home made replacement lacks the flexibility, performance or reliability of the one provided by the framework, not surprising as you're not as experienced and skilled in the details of the standards and protocols as your framework's creator. Invariably, it becomes an obstacle when doing major framework version upgrades. Invariably, it creates additional layers of complexity instead of letting you concentrate on application functionality.

You've chosen a framework. Use it. Extend it. But don't patch it or overcome it. If you find yourself doing that, throw away your framework and pick another one.

Above all, please, please, please, do not fight it. Use it as intended. If you don't like the way it is set up, just do not override 30 methods in 9 classes across 528 lines of code just because you think authentication should follow your three-redirections-across-two-domains flow to decode a session token. Do not create your own versions of a cache just because you can or you don't understand how the built in one works.