-
-
【Go言語】net/httpパッケージの基本的なことまとめ(シンプルなHTTPサーバー実装)
Go言語を学び始めたときnet/httpを使って簡単なものを作ったりしていましたが、echoを使ったプロジェクトに参画してから触れることなく過ごしてきました。 しかしGoでオススメのWebフレームワー ...
続きを見る
↑の記事で net/http パッケージを使ったHTTPサーバーの実装についてまとめましたが、今回はハンドラー関数をラップする方法をメモメモ。
アプリケーションを実装していると、ServeHTTP
メソッドが呼ばれる前後に処理をはさみたいことがあります。
例えば、ログインが必要なハンドラーの場合は未ログインならログイン画面にリダイレクトさせるとか。
このようなときはハンドラー関数をラップすればOK。
サンプルコード
すべてmain.goに書く想定です。
例として、ログインしていなければログインページにリダイレクトさせるAuthHandlerを作ります。
package main
import (
"fmt"
"log"
"net/http"
)
type AuthHandler struct {
next http.Handler
}
func (h *AuthHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
token, err := r.Cookie("auth_token")
if err == http.ErrNoCookie {
// ログイン画面へリダイレクト
w.Header().Set("Location", "/login")
w.WriteHeader(http.StatusTemporaryRedirect)
return
} else if err != nil {
panic(err)
}
// 本来はcookieの値を検証して
if len(token.Value) > 0 {
// ラップされたハンドラを呼ぶ
h.next.ServeHTTP(w, r)
}
}
func MustAuth(handler http.Handler) http.Handler {
return &AuthHandler{next: handler}
}
ログインしている必要がある場合は、この MustAuth
を使えばOK。例えばマイページにアクセスするためにはログインしている必要があるとか。
type MyPageHandler struct{}
func (h *MyPageHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, "マイページ")
}
func main() {
http.HandleFunc("/login", func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, "ログイン画面")
})
http.Handle("/mypage", MustAuth(&MyPageHandler{}))
if err := http.ListenAndServe(":8080", nil); err != nil {
log.Fatal("ListenAndServe: ", err)
}
}
サンプルコード全体
package main
import (
"fmt"
"log"
"net/http"
)
type AuthHandler struct {
next http.Handler
}
func (h *AuthHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
token, err := r.Cookie("auth_token")
if err == http.ErrNoCookie {
// ログイン画面へリダイレクト
w.Header().Set("Location", "/login")
w.WriteHeader(http.StatusTemporaryRedirect)
return
} else if err != nil {
panic(err)
}
// 本来はcookieの値を検証して
if len(token.Value) > 0 {
// ラップされたハンドラを呼ぶ
h.next.ServeHTTP(w, r)
}
}
func MustAuth(handler http.Handler) http.Handler {
return &AuthHandler{next: handler}
}
type MyPageHandler struct{}
func (h *MyPageHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, "マイページ")
}
func main() {
http.HandleFunc("/login", func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, "ログイン画面")
})
http.Handle("/mypage", MustAuth(&MyPageHandler{}))
if err := http.ListenAndServe(":8080", nil); err != nil {
log.Fatal("ListenAndServe: ", err)
}
}
サンプルコード動作確認
go run main.go
して
http://localhost:8080/mypage
にアクセスします。 すると /login
にリダイレクトされます。
次にdeveloper tools でcookieに適当な値を入れて
http://localhost:8080/mypage
にアクセスすると「マイページ」と表示されます。
参考図書
Tour of Goを終えた人にオススメです!!