Devdelly

Adding hot reloading for golang development

December 21, 2019

Hot reloading is a convenient feature many of us don’t want to miss during development. In this post we’re going to have a look at how we can achieve hot reloading for a golang based server application.

Setup

We’ll use a very basic example for our server, with only a single main.go file serving REST calls to /hello:

package main

import (
	"net/http"
)

func main() {
	http.HandleFunc("/hello", helloWorld)
	http.ListenAndServe(":8089", nil)
}

func helloWorld(w http.ResponseWriter, r *http.Request) {
	w.Write([]byte("Hello World"))
}

Running this application via go run main.go and then calling http://localhost:8089/hello results, as expected, in the output Hello World.

Why we want hot reloading

However, every time we need to change anything in our application, we need to stop the server and restart it with the new code. Any developer can tell from experience that this process quickly gets very cumbersome. Wouldn’t it be great if the server restarted automatically with the new code? In the node.js world we achieve hot reloading by using nodemon, but we can do something that acts very similar.

Using reflex to achieve hot reloading

The author of Reflex describes the tool as follows:

Reflex is a small tool to watch a directory and rerun a command when certain files change. It’s great for automatically running compile/lint/test tasks and for reloading your application when the code changes.

This is exactly what we need to achieve our goal.

First we need to install reflex. go get github.com/cespare/reflex

We verify that the installation was successful with:

devdelly:~/server$ reflex
Could not make reflex for config: must give command to execute

This means that the reflex command works, we just didn’t specify a valid command. Great!

The command we need is:

reflex -r '\.go' -s -- sh -c "go run main.go"

Let’s break down the different pieces:

  1. `-r ’.go’ Tells reflex to watch all files ending in go. If a change on such a file happens it will trigger the command
  2. -s Tells reflex that we are running a service, as opposed to a command that will terminate by itself. If this flag is present, reflex will first kill the running service.
  3. sh -c "go run main.go" the part after the tells reflex which command to execute if a change was triggered.

With this in place, our go server will now restart every time one of our go files was changed.


A blog by Manuel about everything related to software development