Gorilla Mux – A router and dispatcher for Go

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 `json:"id"`
    Name string `json:"name"`
    Age int `json:"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.

Share this article: Tweet this post / Post on LinkedIn