Single-Binary Web Apps in Go and Vue — Part 1
By: Adam Presley
Tags: Vue, JavaScript, Software Development, Go, Development

Photo by Gift Habeshaw on Unsplash

Often I find myself tasked with building web applications or APIs with web management portals. On the backend my language of choice is Go, while on the frontend my framework of choice is Vue. One of the big benefits of Go is it compiles into a single binary. When building an API in Go, and a frontend in JavaScript though, these are two different stacks, and as such might mean deploying two different apps. And in some cases that may be desirable. But for my simple uses I’d like to bundle everything into a single binary for deployment, because it makes my life easier.

This is a 4 part series:

Part 1 — The Go and Vue apps

Part 2 — Starting the Vue app with your Go app

Part 3 — Bundling it all up

Part 4 — Automating using Make

In this series we’ll build an app that does nothing useful, but demonstrates bundling your Go and Vue apps into a single binary. This article is part 1, where we will setup the Go and Vue apps separately. There are a couple of prerequisites necessary to get started. Make sure you have the following tools installed.

The Go App

Let’s start with the Go app. In this example we’ll build a a really small app that simply fires up an HTTP server. I’m using the excellent Echo framework for simplifying boilerplate HTTP server stuff. The first step is to initialize a new Go app. In your terminal create a new directory and run go mod init . For these examples, I’m using a namespace of github.com/adampresley/example. Change this to meet your own needs.

$ mkdir example

$ cd example

$ go mod init github.com/adampresley/example

$ touch ./main.go

The above steps will initialize Go modules for our package, and create a blank main.go file. Open up that file and paste the following content. We’ll break down what everything does in a minute.

Let’s break this down.

Line 18 — A global version variable. This is mostly used to announce the version of the application. We’ll muck with this more in part 4

Starting at line 30 we setup our HTTP server using Echo. On line 33 we create a simple endpoint at /api/version which simply returns the Version variable

which simply returns the Version variable At line 37 we create a goroutine which starts the HTTP server listening on port 8080

Line 56–62 creates a channel that waits for an interrupt signal, such as CTRL+C. Execution will pause here, allowing the HTTP server to run indefinitely until it is interrupted

Lines 64–71 tell the HTTP server to shutdown

If you run this now on a terminal using go run . you should see a message stating that the application has started.

The Vue App

The next part of the equation is the Vue JavaScript application. This part is way easier because Vue provides their CLI to set it all up for you. In this section I’ll walk through the choices I made for the example, then demonstrate calling our Go API to get the version and display it on our page.

The first step is to create the app using the CLI tool. We are going to create the Vue app inside our example folder where our Go app is.

$ cd example

$ vue create app

Running the above will start a wizard which asks several questions. Here are the options that I chose for this demo.

Once you’ve made your selections, watch and wait for the CLI to do it’s job. When it complete you should see a message that looks something like this.

Now, if you open two terminals, you can run the Go app in one, and the Vue app in another.

Terminal 1

$ cd example

$ go run .

Terminal 2

$ cd example/app

$ npm run serve

Now open a browser. In tab 1 navigate to http://localhost:8080/api/version and you will see the version string output. Open another tab and navigate to http://localhost:8081 and you will see the default Vue sample page.

Calling the API

Finally, let’s have our Vue app call the Go API version endpoint, just for kicks. In the /app/src/components/ directory there is a file called HelloWorld.vue. Open this file for editing. We want to display the API version string at the bottom of the page. Here are the steps.

Add a variable to hold the version. See lines 41–45

Add HTML to display the version. See line 30

Get the version from the server and assign it to our new variable. We’ll do this when the component is created. See lines 47–51

Here is the code in full.

Now when you refresh http://localhost:8081 you’ll see this.

That’s it for part 1! In part 2 we’ll add code in our Go application which will automatically start the Vue app for us when we run the Go app, adding a level of convienence.