Repository Pattern in Golang (a.k.a. the best way I could think of to pass around the database connection in this oddly hyped language.)
Background
Having been working as a software engineer for almost 5 years, I knew about the hype surrounding Golang for some time but never really worked on a big enough project that drives me to explore the pros and cons and the quirks of the language. Since Covid-19 is forcing me to be a loner, I decided to work on a little project.
The first obstacle that I faced was, “How do I pass around the database instance?” When you use a framework like Ruby on Rails or Django, the framework provides you a way to declare the database connection. By default, you basically have access to the database instance from anywhere in the application.
That’s not the case for Golang. Golang doesn’t have a mature, full-fledged framework like Django backed by thousands of contributors, and you would need to think of a suitable project structure on your own. I discovered a blog post about different ways to pass around the database connection.
I was too lazy to read the entire article (Although I know I’ve been verbosely blabbering about this project's background), but what I got from this article is that the repository pattern is the way to GO! (I know you know what I just did there.)
Structure and Implementation
One of the modifications I made that deviates from what was suggested in the article is that I decided to declare the repository interface inside the user package to decouple the repository's actual implementation and initialize it in the controller, as shown below.
Well, I guess it doesn’t make much sense unless I post the implementation of the repository package…
Then, I Initialized the repository.
Finally, You’ll need to initialize the database connection, repositories, and controllers as follows.
In order to help you understand the project structure, I will link my Github repository here.
I used GraphQL to expose the APIs, using the following library, and it’s actually something I regret the most about this project.
The problem is that it takes roughly 4 to 5 seconds for this application to return a response upon an API call for some reason. I initially suspected that it might be because of Gorm, but after digging into it, I realized it might be because of this GraphQL package. I initially tried to use a library called Thunder, but it was too buggy. I replaced it with the GraphQL package above, but it still poses some performance issues.
(I didn’t spend too much time delving into it, so maybe the lag is caused by Gorm or something else… I have no idea at the moment)
Something to Remember
I discovered this one thing, and I hope it’ll save you some time in the future.
If you ever need to compile a GoLang project for an Operating System that’s different from the one you’re building it on, you will need to specify the target OS by explicitly providing environmental variables.
In my case, I use macOS but decided to use Ubuntu as the development docker image, so I had to run this command.
env GOOS=linux GOARCH=386 go build -o build .
Well, I hope it was helpful in some way…. Happy social distancing!