Go でステータスコードをミドルウェアで取得する
Golang でステータスコードをミドルウェアで取得するようにしてみます
例えば、ステータスコードで400番台が出たら、slackに通知させたい!
何か処理を行いたいとします
前提
routerに gorilla/mux
middlewareに urfave/negroni
を使います
サンプルコード
http://localhost:8080/
にアクセスするとHello, World!
と返し
path が間違っているとエラーを吐くサンプルを作成してみます
package main import ( "fmt" "log" "net/http" "github.com/gorilla/mux" "github.com/urfave/negroni" ) func main(){ router := mux.NewRouter() router.HandleFunc("/", handleRoot) n := negroni.New( ) n.UseHandler(router) n.Run(":8080") } func handleRoot(w http.ResponseWriter, req *http.Request) { if req.URL.Path != "/" { http.NotFound(w, req) return } fmt.Fprintf(w, "Hello, World!") }
negroniでミドルウェアを設定
ミドルウェアを設定します
package main import ( "fmt" "log" "net/http" "github.com/gorilla/mux" "github.com/urfave/negroni" ) func main(){ router := mux.NewRouter() router.HandleFunc("/", handleRoot) n := negroni.New( newStatusCodeChecker(), ) n.UseHandler(router) n.Run(":8080") } func handleRoot(w http.ResponseWriter, req *http.Request) { if req.URL.Path != "/" { http.NotFound(w, req) return } fmt.Fprintf(w, "Hello, World!") } func newStatusCodeChecker() negroni.Handler { return negroni.HandlerFunc(func(w http.ResponseWriter, r *http.Request, next http.HandlerFunc) { next(w, r) }) }
newStatusCodeChecker
の next
の後に行いたい処理を書きます
今回はミドルウェアの中でもメインの処理が行われた後に処理を行いたいので、 next
の後に処理を書くのがポイントです
ミドルウェアについてはこちらの図がとてもわかりやすいです
ステータスコードを取得する
先にコードを
package main import ( "fmt" "log" "net/http" "github.com/gorilla/mux" "github.com/urfave/negroni" ) func main(){ router := mux.NewRouter() router.HandleFunc("/", handleRoot) n := negroni.New( newStatusCodeChecker(), ) n.UseHandler(router) n.Run(":8080") } func handleRoot(w http.ResponseWriter, req *http.Request) { if req.URL.Path != "/" { http.NotFound(w, req) return } fmt.Fprintf(w, "Hello, World!") } type responseWriterWithStatusCode struct { http.ResponseWriter statusCode int } func (lrw *responseWriterWithStatusCode) WriteHeader(code int) { lrw.statusCode = code lrw.ResponseWriter.WriteHeader(code) } func newStatusCodeChecker() negroni.Handler { return negroni.HandlerFunc(func(w http.ResponseWriter, r *http.Request, next http.HandlerFunc) { lrw := newResponseWriterWithStatusCode(w) next(lrw, r) // next 以降の処理は事後処理のmiddlewareとして実行される statusCode := lrw.statusCode log.Printf("StatusCoude: %#v", statusCode) }) } func newResponseWriterWithStatusCode(w http.ResponseWriter) *responseWriterWithStatusCode { return &responseWriterWithStatusCode{w, http.StatusOK} }
コードを見ればわかると思うのですが、やっていることとしては
responseWriter
はステータスコードを持っていないので、statusCode
を持った専用のresponseWriterWithStatusCode
を作成responseWriterWithStatusCode
にステータスコードを書き込むWriteHeader
を作成responseWriterWithStatusCode
をメインの処理に渡す- メインの処理が行われた後に、ステータスコードを取得
となります
実行結果
http://localhost:8080/
にアクセスした場合
2018/04/24 01:17:09 StatusCoude: 200
http://localhost:8080/abc
にアクセスした場合
2018/04/24 01:17:09 StatusCoude: 404
参考:
[Go] Capturing the HTTP status code from http.ResponseWriter · ndersson.me
おまけ
こちらもどうぞ
このブログのTwitterアカウントを作成しました!!
フォロー待ってます!!
twitter.com