Quick links:
I was recently roped into the world of Go (Golang) while working on building the terraform provider for Cisco FMC at work. This beautiful language that amalgamates the speed and friendliness of C to modern creature comforts offered by the likes of Python was a refreshing experience. I had a ton of hands-on with making API calls and handling state in Go. Although I still am yet to explore in-depth the largely uncovered areas of goroutines and channels, before going there, I wanted to understand database ORM modeling, used quite frequently in many backends.
The idea for this project came from when I was searching for something similar to pastebin that I can self-host. I landed on filite , written in Rust, doing more than what I wanted. The only downside what that it was not pre-packaged as a container and stored data in multiple places, making a bind mount bit tedious. It was the perfect opportunity to build something that I was confident I knew enough of Go to write.
I started with a simple Go HTTP server from the wiki
and started building on top of that. I initially followed the same URL syntax of filite
, keeping /l/
for links, /t/
for texts, and /f/
for files. I chose to go with an SQLite database and GORM
, “a fantastic ORM library” (in their words, true to it) to persist state and the filesystem to save the files/texts.
I then started adding the APIs to create these resources, which filite
handled by sending POST requests to the same endpoint. The method of sharing secured and unsecured routes felt off for me to both protect and serve (pun not intended). So, I moved the creation endpoints under an API subpath as /api/v1/
. I made good use of html/templates
and creating custom HTML pages to render the content for the short links. I learned the fascinating Go embed to embed the template files in the binary as done here
. Testing all the APIs was using Insomnia
, a wonderful Postman open-source alternative. I still need to create unit test cases, which I hope I’ll get to when I start learning about mocking and testing in detail.
For the UI to create the resources, I opted for VueJS, which I was familiar with already. Go has a decent static server as well, so I proceeded with the thought of building the Vue site and serve it with the same backend to reduce the number of places where things can go wrong. It was a simple UI made using Vuetify with three tabs for the resources. A further feature addition made it possible to see all the existing links.
Finally, I created a Dockerfile
to build the frontend and backend separately and then a tiny alpine
container which brings everything together by adding the binary and the static files. I added a drone config
to have an automated docker image built and pushed to DockerHub
. If you like to see some builds, head over to the Drone Builds
. I also made good use of Heroku Container Runtime
for deploying an ephemeral demo version which does not persist any data, available here to play around with Short{Paste}
A shoutout to Shields|IO providing beautiful shields which can be added to READMEs, making it look interesting!