ただの勉強メモ程度ですが、httpパッケージ配下のHandle
、HandleFunc
、Handler
、HandlerFunc
についてまとめました。
Goでアプリケーションサーバを書くのはとても簡単で、そこらのLL並みの行数で小さなWebアプリケーションが立ち上がる。
package main
import (
"fmt"
"log"
"net/http"
)
func index(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "hello, go httpd!")
}
func main() {
http.HandleFunc("/", index)
e := http.ListenAndServe(":8080", nil)
if e != nil {
log.Panic(e)
}
}
$ go run ./httpd-sample.go
何のログも出ないですが、これで8080番をリスンするっぽい(logパッケージで細かく出してあげれば出る)。
流れは:
-
http.Handle
やhttp.HandleFunc
でパスごとのハンドラーを指定する -
http.ListenAndServe
で立ち上がりる
便利簡単!
http.HandleFunc
はhttp.ResponseWriter
と*http.Request
を取る関数をそのまま渡せる。
http.Handle
は、http.Handler
インタフェースを実装したオブジェクトを渡す。要するにServeHTTP(http.ResponseWriter, *http.Request)
という関数を実装したオブジェクトであれば良い。以下のような感じ:
package main
import (
"fmt"
"net/http"
)
type AppHandler struct {
appName string
}
func(index *AppHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "hello, %s!", index.appName)
}
func main() {
index := new(AppHandler)
index.appName = "sample app"
http.Handle("/", index)
http.ListenAndServe(":8080", nil)
}
http.HandlerFunc
というものもあり、これは関数を渡せばhttp.Handler
を実装したオブジェクトを返してくれる。
http.HandlerFunc
は実際にはfunc(ResponseWriter, *Request)
の別名だが、ServeHTTP
をちゃんと実装している。ServeHTTP
は自分自身をただ呼び出すだけである。簡潔。
type HandlerFunc func(ResponseWriter, *Request)
// ServeHTTP calls f(w, r).
func (f HandlerFunc) ServeHTTP(w ResponseWriter, r *Request) {
f(w, r)
}
先ほどのHandleFunc
も、実際は中でHandlerFunc
を読んで変換している、と言う感じ。
func (mux *ServeMux) HandleFunc(pattern string, handler func(ResponseWriter, *Request)) {
mux.Handle(pattern, HandlerFunc(handler))
}
次は @hajimehoshi さんです