I recently found myself architecting yet another microservices REST backend. Within the past few years I've written from-scratch backends in Spring, Dropwizard and even in Python using web.py but each has left me wanting more. In this article I’ll show how and why I settled on Spring Boot and JDBI as a combination of frameworks which allows me to easily develop REST services backed by a relational datastore.
REST Frameworks
Let’s compare and contrast some of the modern REST frameworks that can be used today in order to build REST services. There are some obvious ones missing (e.g. Ruby on Rails, Flask, Django, NodeJS) but I’m going to focus on the frameworks that I’ve personally used to build significant production-grade service tiers.
Spring
The grandaddy of modern microservices backends, Spring has great dependency injection (DI) and a large extensive library of addons, but it tends to have long startup time and feels quite heavy and enterprisey when compared to some of the newer microservices frameworks. Spring.io itself recently posted this good article drawing out some of the concerns they’ve heard from developers regarding the Spring framework.
It also features out of the box support for Hibernate as an ORM layer, which (feel free to flame me in the comments) in my experience gets in the way as often as it doesn't. It's great for simple relational structures and is quick to bootstrap solutions but as soon as you're dealing with complex data structures or want specific types of queries (say for efficiency) it becomes quite cumbersome.
Dropwizard
A light-weight Jersey container which provides great support for JDBI as an ORM-light solution. I've found JDBI to be a simple way to interact with a DB. Yes, you have to bind your ResultSet
s to your model objects manually but I've found it a small price to pay for the great flexibility it provides by allowing me to generate the exact queries I want without having to rely on (and trust) SQL auto-generated by an ORM. In my opinion it's a really nice solution that sits somewhere between JDBC and a full-blown ORM.
What Dropwizard doesn't do well is DI. There is support for Guice via extensions like dropwizard-guice but I have found these to be clunky at best. My biggest issue with all of these solutions is that you end up with separate DI graphs for each module. This isn't a problem for simple applications but I've experienced in complex applications that dropwizard-guice becomes quite unwieldy and the separate DI graphs end up having the same class being injected with a different instance/state which can start producing unintended results.
I really just want out of the box DI that is easy to use and gets out of the way. This should be plumbing, not an application feature.
web.py
Well, clearly one of these things is not like the other. I included web.py because I have written a full-featured rest tier in it and if your religion is Python then it's a good choice. If you're actually contemplating a Java-based framework then this obviously isn't your cup of tea.
Spring Boot
Spring Boot is a lightweight version of Spring that is focussed on creating Spring-like applications that "just run". If you're new to Spring Boot there are some excellent getting started guides in the Spring Boot reference guide.
Whereas Spring can feel quite enterprisey, Spring Boot both feels and performs like a true first-class microservices framework due to it’s quick learning curve and snappy startup. It has the same great support for DI as Spring and also features an extensive library of spring-boot-starter-*
maven dependencies that you can use to add support for a great many things.
It still, however, uses Hibernate as it's "native" ORM tier. Now if that's fine for you then go for it, Spring Boot out of the box is a great solution but for me I just find Hibernate too cumbersome.
Hibernate vs JDBI
I've stated that Hibernate "gets in the way" and that JDBI is "a really nice solution", which bears further discussion to draw out a few points. Firstly, there are many Hibernate applications which operate well at scale (and I have developed many), however, there is very much a trend to move away from heavy ORM solutions for some of the following reasons:
- Hibernate can generate large numbers of unnecessary queries, even due to minor misconfigurations (e.g. here and here, just to illustrate a few). When properly configured it still often performs worse than simple SQL queries.
- Hibernate is opinionated about your data structure. When you have a data structure that doesn't folow it's notion of keys and relationships the Object-relational Impedance Mismatch is going to hit you even harder. Hybrid-ORM frameworks, such as JDBI, allow more flexibility when mapping to objects and thus provide more runway before you have to start coding significant work arounds for this issue.
- You don't see the performance problems until you scale! When your application is small and simple everything seems to go along smoothly, then you scale and all of a sudden hibernate queries are the root of your performance problems. I've myself hit this situation many times and it's always taken significant rework to fix the issues.
This quora post is an excellent discussion that reinforces some of the points I make above and also touches on others. Note that I am not trying to hate on Hibernate here. It’s a good tool and when configured correctly can have great performance in a number of situations (I have personally written high scale solutions using Hibernate as the ORM).
So this certainly isn't a right-or-wrong discussion and I do not want to suggest that JBDI is the cure to all evils. But it is an alternative to a "heavy" ORM like Hibernate and can make your life easier as a developer. I have personally encountered many tech companies which are happily using JDBI inside Dropwizard and would not move back to using Hibernate.
So what's a savvy software engineer to do?
Continue reading %Combining Spring Boot and JDBI%
by Damian Hagge via SitePoint
No comments:
Post a Comment