I am unable to sleep because of fever so I thought let me write this post. Maybe it is not the best time to write this post but who cares. A couple of weeks back I got into discussion with a customer CTO over libraries over framework. This customer wants us to prefer libraries over framework.This was mainly with regard to Spring Boot vs Dropwizard discussion.
The best definition I have read on the web about framework and library is that a framework calls your code and your code calls the library API. A framework does much more and has strong opinions. Libraries are focussed, solve one problem, and swappable (not entirely true without proper abstractions).
The customer wanted us to use Dropwizard instead of Spring Boot because of the following reasons:
- Spring Boot does too much auto-magic. With something like Dropwizard you can have control over how things bind together. You can use manual dependency injection instead of a IoC container doing that magic for you. You can disable auto configuration in Spring Boot. You can also wire beans by hand if you want. But, I agree the default way is to rely on auto-configuration.
- Spring Boot vulnerability surface area is higher because it is too easy to add starter jars and bring all the transitive dependencies. I think this will be mostly true with any other approach of building software in Java unless 1) you are going down the stackless way(I don’t think Java platform is there yet) 2) you have good governance on what gets in your dependencies.
- Spring Boot executable size is much higher. I compared bare bones Spring Boot(spring-boot-starter-web with Tomcat) and Dropwizard(default maven archetype) executable sizes. As it turns out Spring Boot was 17M and Dropwizard was 19M.
- Spring Boot startup time is higher. This depends a lot on what you are doing at startup. The bare bone spring boot app starts in 1.64 seconds whereas the bare bone Dropwizard app took 1.526 seconds to startup.
- Spring Boot consumes much more memory. This was true. Spring Boot loaded 7591 classes whereas Dropwizard loaded 6255 classes. Also, heap space consumption of Spring Boot was twice compared to Dropwizard.
- Spring Boot apps are difficult to debug. I agree exception stacktraces are too long at times and it takes a minute or two to reach your calling code. But, I personally never had much trouble debugging Spring Boot apps. I mostly rely on good tests and logging to debug stuff.
- Lastly, they wanted us to follow a general principle – prefer libraries over frameworks.
The funny part is Spring Boot does not call itself a framework and Dropwizard documentation states Dropwizard straddles the line between a library and a framework.
We went with Dropwizard :). I respect their decision and I think their reasons have merit. I myself have seen too many badly architected/built Spring Boot apps so I am open to trying out a new, simpler, and better alternative.
I have read the Brandon Smith post – Write Libraries, not Frameworks. I also think libraries over frameworks is a good architecture principle that we should strive for. The only problem is when we apply principles blindly without understanding the context.
I think principles like favouring libraries over frameworks are fundamental. For these principles to work you need to have the right context and provide the right environment. I think it will work for you when:
- You have a good engineering team that understands the cost of adding libraries. There is no free lunch. It does not work in a typical bottom heavy pyramid team structure where teams are considered feature factories. They will add any library under the roof to deliver features if your mindset is not aligned with the principle.
- You have good governance. It is enforced by healthy code reviews, automation (aka fitness functions), architecture knowledge sharing sessions, Microservices production readiness reviews, and architects with the skin in the game.
- You spend effort and resources on developer experience to build tooling that makes it easy to scaffold new Microservices with your opinions and choices baked in. I am not sure how it will be any different from a pure framework approach. You will end up building your own Microservices framework with your library choices.
- You train your software engineers to buy into this methodology. They will have to unlearn the existing way and learn the new way to build software.
- You understand productivity might take a hit till developers understand the new way to build software. Frameworks give you a productivity boost by helping you get started faster and solving common problems for you.
- You use automated checks to continuously prove that software is not deviating from the principle. You can write a build tool task that fails the build if executable size reaches a threshold. You can write tests that fail the build if people use certain libraries. All of this is possible. You need to invest the time of the right engineers to make this happen.
I don’t know whether this will work in our environment or context. It will depend on if we can walk the talk. I have seen too many times all the good things thrown under the bus when business puts pressure for features.
Looks like medicine(or writing this post) has done its job. I started writing at 2:28am and now at 3:39am my fever is down and I am feeling better.