この本について
Goのnet/http
パッケージはとても使い勝手がよく、コードを数行書いただけですぐにWebサーバーの"Hello World"ができるようになります。
// Hello Worldの一部
h1 := func(w http.ResponseWriter, _ *http.Request) {
io.WriteString(w, "Hello from a HandleFunc #1!\n")
}
http.HandleFunc("/", h1)
log.Fatal(http.ListenAndServe(":8080", nil))
自分が使いたいハンドラを書き、それをどこのURL・ポート番号で起動させるかということを宣言的に指定するだけで、簡単にその要件を満たしたWebサーバーが起動します。
ですが、この裏に何が行われているのか考えてみたことはありますか?
筆者はこれをやったときに、
-
net.Listen()
とかln.Accept()
とかやらなくていいの? - リクエストをネットワークから「Readする/読み込む」ような処理がどこにも書かれてないけど、どこでやってるの?
-
http.HandleFunc
関数に登録しているハンドラって、どこに行くの?どこに保存されるの? - ハンドラに出てくる第一引数
http.ResponseWriter
って何者?なんでこれに書き込むだけで勝手にレスポンスになるの? - そもそも
http.ListenAndServe
の第二引数nil
っていいの?
などというポイントが気になってしかたがありませんでした。我ながらめんどくさい性格してると思います
実際にGoのWebサーバーが行っている「コネクションを確立してリクエストを読み込んで……」という手続き的な処理については、net/http
の中にまるっと隠蔽されユーザーが気にしなくていいようになっているので、それを知りたいなら実際にコードリーディングをするのが一番の近道でした。
この本では、当時私が抱いた疑問の答えを見つけるためにnet/http
パッケージのソースコードを読み漁って得た内容を、わかりやすくまとめ図式化したものを共有するために執筆したものとなります。
これを通して、「GoのWebサーバーの中身、ちょっとわかる」となってもらえたら嬉しいです。
本の構成
2章 ウェブサーバーのHello, World
この章では、「サーバーの中身の前に、どうやってGoでサーバーを立てるの?」というところを軽く紹介します。
3章 httpサーバー起動の裏側
ここでは、http.ListenAndServe
関数が実行されてから、その第二引数に渡されたルーティングハンドラが起動するところまでのソースコードを追っていき、流れを図示しています。
4章 デフォルトでのルーティング処理の詳細
この章では、ListenAndServe
関数の第二引数がnil
であった場合、デフォルトで採用されるルータDefaultServeMux
の
- ハンドラ登録
- ハンドリング処理
の仕組みについて、net/http
のソースコードを追って図示しています。
5章 ハンドラによるレスポンス返却の詳細
ここでは、ユーザーが用意したハンドラ関数func(w http.ResponseWriter, _ *http.Request)
に関して、
- 第一引数
http.ResponseWriter
は何者なのか -
http.ResponseWriter
の書き込みメソッドを実行するだけで、ネットワークに載せるレスポンスが作れてしまうのはどういう仕組みなのか
という2点についてまとめました。
6章 GoでのWebサーバー起動の全体図
最後に、3~5章に渡って説明してきた内容の要点だけを抽出し作成した「Goでウェブサーバーを起動したときに裏で起きている概要図」をここで紹介します。
使用する環境・バージョン
- OS: macOS Catalina 10.15.7
- go version go1.17 darwin/amd64
読者に要求する前提知識
- Goの基本的な文法の読み書きができること