When writing web applications we often reach to ORMs to help us with the connection to the database layer. This is something that generally speed up the development of applications, but has a tradeoff in performance and complexity. I have worked in some very large code bases that took an expensive performance hit from the ORM. Some of the queries that were generated where interesting.
Writing SQL directly is usually going to have better performance characteristics than auto-generating SQL queries based on a model. Especially as the complexity of the data grows. There are downsides with this, having to write loading and saving logic being a big time cost. It’s also important to write tests to ensure that there is no regression if there are changes in the data model.
Golang has first class code generation tools built into the compiler that allows us to generate structures and methods based on specifications. And there are libraries that take advantage of this by allowing you to directly generate your model structs based on the database schema.
Go-Jet is one of these and what it also does is allow us to write typesafe SQL code that will fail the build if the SQL doesn’t match the database.
Example of a simple query:
|
|
While you end up writing more code, you have direct control over the query that is sent to the database. It means you don’t have to consider lazy-loading and other abstractions and complexities that comes with an ORM, you load exactly the data you need and work with that. The simplest approach is most often the best, especially as the overall size of the application increases. Writing good abstractions is incredibly hard, and it’s often better to not take on that complexity if you want to build good maintainable code.
I’ve been using Go-Jet in my lasts applications and it has been a joy to work with, definitively worth looking into if you’re building an app in golang.