Goの標準ライブラリでWebサーバを構築
from Goを学ぶ
手を動かす
メンタルモデル
Request: ユーザーからのアクセスが到達
Layer 1 (Middleware): loggingMiddleware がキャッチ. 開始時間を記録
Layer 2 (Mux): ServeMux がURLを見て振り分け (/ なのか /assets/ なのか)
Layer 3 (Handler):
Case A: homeHandler が実行され,TemplateエンジンがHTMLを生成
Case B: FileServer が実行され,画像をディスクから読み込み
Response: 処理結果が逆順で戻り,最後にMiddlewareが所要時間を計算してログ出力し,クライアントへ返却
1. HTTPハンドラを作成, 1h
*Goの関数が ResponseWriter を通じてHTTPレスポンスを書き込む,Webサーバの最小実行単位の仕組みを理解する
go mod init lab-site を実行
main.go を作成
ハンドラ関数 func homeHandler(w http.ResponseWriter, r *http.Request) を定義
w.Write([]byte("Hello, World")) で文字列を書き込む
http.HandleFunc("/", homeHandler) で登録し,http.ListenAndServe(":8080", nil) で起動
確認: ブラウザで localhost:8080 にアクセスし表示を確認
2. ルーティングを作成, http.ServeMux, 1.5h
* グローバルな設定(DefaultServeMux)に頼らず,自分で ServeMux インスタンスを生成・管理し,サーバーに渡す明示的な依存関係を理解する
mux := http.NewServeMux() を main 関数内で宣言
新たに func aboutHandler (研究室紹介用) を作成
mux.HandleFunc("/", homeHandler) のように,ルート (/) と対応するハンドラを mux に登録
mux.HandleFunc("/about", aboutHandler) のように,/about パスと対応するハンドラを mux に登録
サーバー起動部分を http.ListenAndServe(":8080", mux) に変更(引数を nil から宣言した mux へ)
確認: ブラウザで / と /about にアクセスし,表示が変わることを確認
3. テンプレートを作成, GoのStructをHTMLに流す, 4h
*Goの構造体を解析・展開し.HTML (表示) とプログラム (ロジック) をデータバインディングする手順を理解する
templates/layout.html (共通部分) と templates/index.html (中身) を作成
main.go に表示用データ構造体 type PageData struct { Title string; Body string } を定義
ハンドラ内で template.ParseFiles を使い,HTMLファイルを読み込む
tmpl.Execute(w, data) で構造体 data をHTMLに流し込んでレスポンス
確認: Goのコード内の文字列を変更してリロードし,HTMLが変わることを確認
4. Static serverを作成, http.FileServer + http.StripPrefix, 15.h
*URLのパス(Web上の住所)とディレクトリのパス(OS上の実住所)をマッピングし,そのズレを StripPrefix で解消するファイル配信の仕組みを理解する
assets/css/style.css を作成し、背景色などを変える記述をする。
main.go にファイルサーバー用ハンドラを追加:
code: Go
fileServer := http.FileServer(http.Dir("./assets"))
mux.Handle("/assets/", http.StripPrefix("/assets/", fileServer))
※ StripPrefix が重要です。URLの /assets/ 部分を取り除いてからファイルを探させる処理です。
HTMLテンプレート内で <link rel="stylesheet" href="/assets/css/style.css"> を記述
確認: ページのデザインが適用されていることを確認
5. ミドルウェアを作成, 3h
*ハンドラ関数を別の関数で包み込み,リクエスト処理の前後に共通処理を注入するミドルウェアパターンの設計を理解する
func loggingMiddleware(next http.Handler) http.Handler を定義
処理内容:
1. start := time.Now()
2. next.ServeHTTP(w, r) (本来のハンドラを実行)
3. log.Printf(...) でメソッド、URL、所要時間を出力。
main 関数で、Mux全体をラップする:wrappedMux := loggingMiddleware(mux)
起動部分を http.ListenAndServe(":8080", wrappedMux) に変更
確認: ページをリロードするたびに、ターミナルにログが出ることを確認
マージン 4h
ひとまずBuild Web Application with Golangで学習する
https://pkg.go.dev/net/http
https://pkg.go.dev/html/template
https://www.oreilly.co.jp/books/9784814400836/