Golang Mux 路由使用

Web 应用通过使用路由就能实现基本的框架功能,Go 自带了 Http 路由,但是使用起来不太方便,这里的一个 gorilla/mux 路由比较不错的,虽然并不是最快的,但是是功能最全的,API 也设计得比较不错。

简单示例:

package main

import (
    "encoding/json"
    "github.com/gorilla/mux"
    "log"
    "net/http"
)

type User struct {
    Username string
    Email string
    Age uint8
}

func HomeHandler(w http.ResponseWriter, r *http.Request) {

    user := &User{
        Username: "twn39",
        Email:    "twn39",
        Age:      13,
    }

    result, _ := json.Marshal(user)
    w.Header().Set("Content-Type", "Application/json;Charset=UTF-8")
    w.WriteHeader(http.StatusOK) // 这里的 status code 可以不设置,但是设置了之后一定要放在最后面,不然其它的 header 无法覆盖和设置
    w.Write(result)
}

func main() {
    router := mux.NewRouter()
    router.HandleFunc("/", HomeHandler)
    log.Fatal(http.ListenAndServe(":8080", router))
}

注: 这里需要注意的是当需要设置头部时,w.WriteHeader(http.StatusOK)的顺序

Middleware

Mux 支持 Middleware 有点像 Nodejs 的 Express, 定义一个路由非常简单:

package middleware

import (
    "github.com/sirupsen/logrus"
    "net/http"
    "os"
)

func Logger(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        logrus.SetOutput(os.Stdout)
        logrus.SetLevel(logrus.InfoLevel)
        logrus.WithFields(logrus.Fields{
            "uri": r.RequestURI,
        }).Info("logger...")
        next.ServeHTTP(w, r)
    })
}

然后在 main 中加入即可:

func main() {
    router := mux.NewRouter()
    router.HandleFunc("/", HomeHandler)
    router.Use(middleware.Logger)
    log.Fatal(http.ListenAndServe(":8080", router))
}

例如全局设置 Content-Type 头:

package middleware

import (
    "net/http"
)

func JsonResponse(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        w.Header().Set("Content-Type", "Application/json; Charset=utf-8")
        next.ServeHTTP(w, r)
    })
}

然后使用:

func main() {
    router := mux.NewRouter()
    router.HandleFunc("/", HomeHandler)
    router.Use(middleware.Logger)
    router.Use(middleware.JsonResponse)
    log.Fatal(http.ListenAndServe(":8080", router))
}