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:
- `-r ’.go’ Tells reflex to watch all files ending in go. If a change on such a file happens it will trigger the command
-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.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 Kruisz a Freelance Software Developer based in Vienna