In my previous blog about the Go programming language we saw how easy it is to create a HTTP server with a few lines of Go. This time we are going to look at Gorilla Mux (Mux), a full featured router and dispatcher.
Simple HTTP Server
The net/http package provides HTTP client and server implementations. We can create a simple server and register a function with HandlerFunc that handles HTTP requests.
package main
import (
"io"
"net/http"
)
func IndexHandler(w http.ResponseWriter, req *http.Request) {
io.WriteString(w, "Hello, world!n")
}
func main() {
http.HandleFunc("/", IndexHandler)
http.ListenAndServe(":8080", nil)
}
Mux
Mux provides the same router/dispatcher feature as ‘http.Handlefunc’, in that it matches incoming requests against a list of registered routes and calls the handler function.
package main
import (
"github.com/gorilla/mux"
"io"
"net/http"
)
func IndexHandler(w http.ResponseWriter, req *http.Request) {
io.WriteString(w, "Hello, Mux!n")
}
func main() {
r := mux.NewRouter()
r.HandleFunc("/", IndexHandler)
http.Handle("/", r)
http.ListenAndServe(":8080", nil)
}
Mux Matching
Mux has a more rich matcher engine than Go by default provides. Mux can also match requests based on URL host, path, path prefix, schemes, header and query values, HTTP methods, or you can write your own custom matcher. The paths can have variables and regex expressions to match.
package main import ( "encoding/json" "github.com/gorilla/mux" "io" "log" "net/http" "strconv" ) type Cat struct { ID int <code>json:"id"
Name stringjson:"name"
Age intjson:"age"
} var cats = []Cat { Cat { ID: 1, Name:"Elsa", Age: 16 }, Cat { ID: 2, Name:"Tijger", Age: 12 }, } func IndexHandler(w http.ResponseWriter, req *http.Request) { io.WriteString(w, "Hello, Mux!n") } func CatsHandler(w http.ResponseWriter, req *http.Request) { w.Header().Set("Content-Type", "application/json") json.NewEncoder(w).Encode(cats) } func CatHandler(w http.ResponseWriter, req *http.Request) { w.Header().Set("Content-Type", "application/json") params := mux.Vars(req) id, _ := strconv.Atoi(params["id"]) for _, cat := range cats { if cat.ID == id { json.NewEncoder(w).Encode(cat) return } } w.WriteHeader(http.StatusNotFound) } func main() { r := mux.NewRouter() r.HandleFunc("/", IndexHandler).Methods("GET") r.HandleFunc("/cats", CatsHandler).Methods("GET") r.HandleFunc("/cats/{id:[0-9]+}", CatHandler).Methods("GET") http.Handle("/", r) log.Fatal(http.ListenAndServe(":8080", nil)) }
Conclusion
The Go standard library provides HTTP server implementations with basic router/dispatcher functionality. Most often you need a more rich matching engine and Gorilla Mux provides one. It can match requests based on URL host, path, path prefix, schemes, header and query values, HTTP methods, and even on regex. Next time we’ll use Mux in an Google App Engine example.