🔖
【Go入門】ServeMux・DefaultServeMuxの違いをやさしく解説!—ルーティングの基本とミドルウェア適用のコツ
1. ServeMux(マルチプレクサ)とは
私はそもそも、ServeMuxを知らなくて『あなた、マルチプレクサっていうのね!?』という状態でした。
そこで、何に使うのか調べてみたら、どうやらこういう事らしい、、、
ServeMuxは、GoのWebサーバーで「どのURLに来たリクエストを、どのハンドラ(処理関数)に渡すか」を決める“分岐装置”です。
たとえば、
/api/v1/todos
に来たリクエストはTodosHandler
へ/api/v1/users
ならUsersHandler
へ
というように、URLごとに処理を振り分けます。
と理解した。でもそれって、以下のルーティング処理と何が違うの?
go
http.HandleFunc("/api/v1/todos", TodoHandler)
http.HandleFunc("/api/v1/users", UserHandler)
http.ListenAndServe(":8080", nil)
と思っちゃったわけです。
2.マルチプレクサの種類
もうすこし突き詰めて調べると、私は知らないうちにマルチプレクサを使ってました。
先ほど記載したルーティング処理、『このアドレスにリクエストがあったら、Todoハンドラを使って』と、仕分け条件を記載しただけなんです。(正確には仕分け条件をdefaultのマルチプレクサに登録しただけ、、、)
そして誰が仕分けするんだ、というとここで登場するのがマルチプレクサです。
① デフォルトのマルチプレクサ(http.DefaultServeMux)
Goの標準HTTPサーバーは、最初から「DefaultServeMux」という分岐装置を持っています。
-
http.HandleFunc()
やhttp.Handle()
でハンドラを登録すると、このDefaultServeMuxに自動で登録されます。 -
http.ListenAndServe(":8080", nil)
のように第2引数にnil
を渡すと、DefaultServeMuxが使われます。
ここまで理解して、やっと自分が書いたルーティング処理の意味が理解できました。
使い方例
go
http.HandleFunc("/hello", helloHandler) // DefaultServeMuxに仕分け条件を登録
http.ListenAndServe(":8080", nil) // nilを指定するとDefaultServeMuxが使われる
この場合、/hello
にアクセスが来たら helloHandler
が呼ばれます。
はい、DefaultServeMuxが仕分けしてくれたんですね。
② 自分でServeMux(mux)を作る場合
DefaultServeMux以外にも、自分専用のServeMux(分岐装置)を作ることができます。
これは、ミドルウェア(CORSなど)を全体にかけたいときや、複数のルーティングをまとめたいときに便利です。
使い方例
go
mux := http.NewServeMux() // 新しいServeMuxを作成
mux.HandleFunc("/hello", helloHandler)
mux.HandleFunc("/world", worldHandler)
http.ListenAndServe(":8080", mux) // これでmuxが使われる
4. 違いとポイント
DefaultServeMuxを使う場合 | 自分でServeMuxを作る場合 | |
---|---|---|
登録方法 | http.HandleFunc(), http.Handle() | mux.HandleFunc(), mux.Handle() |
ListenAndServe | 第2引数にnilでDefaultServeMux | 第2引数にmuxを渡す |
ミドルウェアの適用 | 全体に適用しにくい | 全体に適用しやすい |
5. まとめ
- ServeMuxは「リクエストの分岐装置」=「URLごとに処理を振り分ける役割」
- DefaultServeMuxはGoが最初から持っている分岐装置
- 自分でServeMuxを作ると、ミドルウェア(CORSなど)を全体にかけやすい
GoでWebサーバーを作るときは、どのServeMuxを使うかを意識すると、より柔軟な設計ができるようになります!
Discussion