🔖

【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