【Go言語】http周りを調べてみた ~ ListenAndServeは何をしているのか

golangのhttpに入門してみて、自作のハンドラー作成 -> 登録 -> サーバ起動の流れはだいたいわかった。

しかし自作のルータ(mux)を作成しようと考えると全くどこから手をつけたらいいのかわからない。

そこで、デフォルトのServeMuxを調べた。

http.ListenAndServe(":8080", nil)
//http.ListenAndServe(":8080", myMux)

よくみるのが上記の形だ。ListenAndServeの第二引数にmuxを指定できる。

ここに渡せるmuxとは何なのかを知るために、ListenAndServeの定義を見てみると、

func ListenAndServe(addr string, handler Handler) error

このようにHandler型であることがわかる。

HandlerはインターフェースでServeHTTPを持つ。

type Handler interface {
        ServeHTTP(ResponseWriter, *Request)
}

つまり、よくみる自作ハンドラーもmuxもどちらもHandler型なのだ。

実験するために以下のコードを作成した。

package main

import (
    "net/http"
)

func main() {
    router := NewRouter()
    http.ListenAndServe(":8080", router)
}

// ---- 自作mux ----
type Router struct {}

func NewRouter() *Router {
    return new(Router)
}

func (router *Router) ServeHTTP(w http.ResponseWriter, r *http.Request) {
    fmt.Print("Router::ServeHTTP\n")
    fmt.Print(r.URL.Path + "\n")
}

上記にコードを実行し、アクセスしてみる。

[http:localhost:8080/aaa]にアクセス

Router::ServeHTTP
/aaa

[http:localhost:8080/hoge/huga/huni]にアクセス

Router::ServeHTTP
/hoge/huga/huni

つまり、ListenAndServeはアクセスが発生した際に、第二引数で指定したHandlerのServeHTTPを実行する。

そのため自作のmuxでルーティングを行う場合は、ServeHTTPを実装(Handlerインターフェース)してその中でアクセスされたパスに対しての検証を行えば良いと思われる。