Building a Go and Vue.js Web Application

14. September 2018 Blog 0

A few months ago at work we were facing a decision, we had to do some major rework to our web app. Our first version was written in Node.js, and no one on our team was really happy with Node for many different reasons. However, one of the main reasons was simply the fact that Javascript is an a synchronous language. Your entire code base becomes a bunch of promises and/or async/await statements. If you have ever written a web application how often do you need a synchronous functionality? For me the answer is not very often. So I would prefer a language that is synchronous by default but allows for async when you need it.

I had been playing around with Go for a few years. The last two years I had been doing the adventofcode.com with Go after running into some insanely long run times doing some the exercises with JS and PHP. Go would run some of these super complex algorithms (like path finding and simulations) in no time at all. I kept saying I wanted to eventually start building some web applications with Go but never really had a chance.

When we started to discuss the idea of rebuilding our web app someone threw out the idea of building the API with Go and using Vue.js for the frontend. I had played with Vue in the past and really liked it. It was very similar to React, however for a few small reasons I just liked Vue more. My only fear was that no one on the team had any real experience with Go. I had the most experience and I hadn’t done hardly any web stuff with Go. But we decided to make the jump and started to move ahead with the plan.

First I looked to see if there were any popular frameworks or packages people used when creating RESTful APIs in Go. There are a few Go frameworks but most of them are pretty early in their development life cycle. After reading quite a few articles almost everyone recommended building without one of these frameworks. So the decision was made to not use a framework for our API.

My first step was to learn how Go’s http package worked. When the creators of Go created the language they wanted to include http as part of the language, it wasn’t an after thought like a lot of other programming languages. So Go by default has an http server built in with routing and most of your basic functionality. After playing around with this for a little while I realized their core router was a little simplistic for what I wanted to do, so I did some research and found gorilla/mux a Go router that added a decent amount of functionality like sub routers, prefixes, middleware, etc… A lot of people seemed to be using this package and I didn’t want to recreate the wheel so I decided we would use it for routing.

This brought up a new issue though, package/dependency management. With Node.js we have npm/yarn, with PHP we have composer, with Python we have pip, etc… So what options are there for Go? Unfortunately this is one of Go’s weakest points right now. There really isn’t a great option. There is go get however that just installs packages locally, so if another develop was working on the code they wouldn’t know you added dependency to the project, there is no package.json or composer.json or any other type of file like that. vgo is super early in development. So really the only option that would work for us was dep, dep has been around for a while and while not great it gives you a  Gopkg.toml and a Gopkg.lock so you can keep track of what dependencies you have added and version numbers.

So now that I had this all figured out I started to actually write some endpoints. However, things quickly started to get unorganized, which I hate. One of my favorite things about frameworks is they give an organization structure for where code should be. It makes it that much easier for other developers to find code and for you to find other people’s code. I found a github repo that had a pretty code project structure that I liked so I decided to mimic theirs.

After writing some mock endpoints now came the issue of actually connecting to a database and storing/retrieving data. When I used PHP I used Laravel and loved their ORM and the database migration features. When we used Node we used sequelize which offered some of that similar functionality. So it was time to find out if there was an ORM with migrations for Go. I pretty quickly realized the answer to that question was “not really”. Yes there were some ORMs and yes some of them had some migration type features, but none of them really had the features I was looking for. So first I decided to pick out an ORM and decided on Gorm. Gorm gives some low level migration options but it doesn’t give you versioning and options like up and down commands. So then I looked for other migration packages and found Goose. Goose gives you the ability to create migration files, and go forward and backwards. So by using these two packages we got the basic functionality we were looking for, we could now programmatically modify our database structure and also use an ORM to provide some abstraction from the database directly.

When you first start writing a decent size codebase in Go you will probably run into things like import cycles and other minor quirks you don’t really have to worry about in most other languages. One of the other biggest pains we had was working with JSON. Since Go is so strictly typed, you can’t just pull in JSON from another API and convert it to an Object/Array like you can in PHP or Javascript. You have to know the exact structure the JSON will be in and what types of data is. If there is nested data you need to know that also. Otherwise when you try to convert from JSON to an interface or map you will run into major issues.

After we had all this in place the rest of the code was pretty easy to write. So the learning curve was a little steep at the beginning but once we got over that hump we cranked out the rest of the API pretty quickly. We were then able to write our frontend in Vue.js without any problems at all. The combination of Go on the backend and Vue on the frontend is awesome. The user experience is amazing, everything loads insanely fast and even though we have code that displays loaders while data is being retrieved via ajax I personally have never even seen them show up because the api is so fast. Not only is the API fast the footprint on the server is so low that I thought our reporting was incorrect. When we first loaded it onto Heroku it showed that the Memory Usage was 8MB. I thought for sure something went wrong with our deployment, but I tried to hit the api and sure enough it responded. So I decided to do a decent load test on it, I think the highest I saw the Memory Usage get was around 20 MB. I also ran an apache benchmark test in my own local development environment. Even hitting an endpoint that hit the database I could pretty easily get round 7,000 requests per second running ab -t 10 -c 100 http://127.0.0.1:8000/api/users/1.

So overall I would say we are really happy with our decision to move to a Go and Vue stack. We are comfortable with both and really enjoy working with them. The only downside is transitioning between javascript (Vue) and Go since there are some syntactical differences, you start adding semicolons into your Go code, or adding parentheses around if statements, but nothing major. If you are looking to write/rewrite an API I would highly encourage you to take a hard look at Go and see if it would be a good fit.


Leave a Reply

Your email address will not be published. Required fields are marked *