I love using Go for HTTP services. In February 2024 the Go team released 1.22 which brought a new standard for routing in Go. Previously the standard way of doing HTTP routing was using the excellent gorilla/mux library. However in my quest to remove as many external dependencies from my code as possible I am now migrating to using the new routing system. My main issue is that the Go doc doesn’t really have much example code but rather is a definition of behaviors. This post is mainly as a reference for myself for common patterns in HTTP routing. I will also update this with other snippets as I find other common patterns.
Important Notes
- Order MATTERS! In general you want the most specific route first and the least specific route last.
Variable in Path
For a path of /pokemon/{id}
we can get the path parameter with r.PathValue("id")
.
// handles anything in /pokemon/*
// doesn't handle anything like /pokemon/{id}/image
http.HandleFunc("/pokemon/{id}", func(w http.ResponseWriter, r *http.Request) {
id_str := r.PathValue("id") // get id
})
Limiting HTTP on Methods
// only accepts POST requests on the route
http.HandleFunc("POST /images/{id}", func(w http.ResponseWriter, r *http.Request) {
})
Getting URL Query Params
// AuthRequired is a middleware function that uses the db and a handler
http.Handle("GET /search", AuthRequired(db, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
query := r.URL.Query().Get("q")
})))
Matching on Domains
http.HandleFunc("lukaswerner.com/hello_world", func(w http.ResponseWriter, r *http.Request) {
// only accepts connections from the lukaswerner.com domain
})
Matching on Path and All Sub-paths
// handles all static content
http.HandleFunc("GET /static/", http.FileServerFS(staticFS))