Go 1.6 で HTTP Request Context
Go 1.6(for Google App Engine)で、Go 1.7 の HTTP Request Context のような事をするメモ。
golang.org/x/net/context
だけでいけるかな〜と思ったけど、そんなわけなくて、ゴリラ系のフレームワークを使った。
フレームワーク
なるべく簡素にしたいし、http.Handler をそのまま使いたかったので、以下を選択。
- GitHub - gorilla/context: A golang registry for global request variables.
- コンテキスト管理
- GitHub - gorilla/mux: A powerful URL router and dispatcher for golang.
- ルーティング管理
- GitHub - urfave/negroni: Idiomatic HTTP Middleware for Golang
- ミドルウェア管理
gorilla/context
が HTTP Request Context
の代替です。
リクエストオブジェクトをキーにして値をグローバルな変数に保管する的なことをしている。
自前のミドルウェアを用意して、リクエスト毎に値を保つコードを書くとこんな感じ。
import ( ... "github.com/gorilla/context" ) ... func MyMiddleware(w http.ResponseWriter, req *http.Request, next http.HandlerFunc) { bag := &ExampleBag{} context.Set(req, "contextKey", bag) // http.Request毎に保管する next(w, req) // MyHandler 呼び出し context.Delete(req, "contextKey") } ... func MyHandler(w http.ResponseWriter, req *http.Request) { bag, ok := context.Get(req, "contextKey").(*ExampleBag) ... }
Go 1.7 > では
func MyMiddleware(w http.ResponseWriter, req *http.Request, next http.HandlerFunc) { bag := &ExampleBag{} ctx := context.WithValue(req.Context(), "contextKey", bag) // req.Context 便利 next(w, req.WithContext(ctx)) } ... func MyHandler(w http.ResponseWriter, req *http.Request) { bag, ok = req.Context().Value("contextKey").(*ExampleBag) ... }
番外
Go 1.7 になったら、下記フレームワークに置き換えたい