【Go】net/httpのPath Parameterパース
net/http の handleFunc() handle() に登録できるパスは Path Parameter を認識しない。例えば、他の Web フレームワークのように、下記 /products/:id エンドポイント中の :id を変数として取得することができない。
// :idを変数としてパースできない http.handleFunc("/products/:id", f)
Path Parameter を取得するためには、Path Parameter 抜きのエンドポイントへのリクエストを一旦ハンドルし、そのハンドラの中で Path Parameter をパースする必要がある。
func main() { http.handleFunc("/products/", handleProducts) http.ListenAndServe(":8000", nil) } func handleProducts(r *http.Request, w http.ResponseWriter) { sub := strings.TrimPrefix(r.URL.Path, "/products") _, id := filepath.Split(sub) if id != "" { // :idを使う... } }
/products/:id リクエストへのハンドラを設定する際には、 /products ではなく /products/ へハンドラを設定する。 /products リクエストハンドラは /products/:id リクエストを受け付けられないため。ただし /products/hoge /products/hoge/fuga などの適当なエンドポイントも受け付けてしまうので、404 を返すなど適宜処理する。
備考
Handle() HandleFunc() に登録できるパスパターンは、 net/http 中の構造体 ServeMux のルールに従う。
パターンは、「/ favicon.ico」のような固定されたルート化されたパス、または「/ images /」のようなルート化されたサブツリーに名前を付けます(末尾のスラッシュに注意してください)。長いパターンは短いパターンよりも優先されるため、「/ images /」と「/ images / thumbnails /」の両方にハンドラーが登録されている場合、「/ images / thumbnails /」で始まるパスと前者のハンドラーが呼び出されます。 「/ images /」サブツリー内の他のパスのリクエストを受け取ります。