Go

Explain the Go 1.22 ServeMux enhancements: method matching, wildcards, and precedence rules.

Question 444MediumGo 1.22 to 1.25

Since Go 1.22, patterns have the form [METHOD ][HOST]/[PATH]:

  • "GET /items/{id}" — method + a single-segment wildcard, read via r.PathValue("id"). GET also matches HEAD.
  • "/files/{path...}" — a trailing multi-segment wildcard capturing the rest.
  • "/{$}" — matches exactly / (without {$}, a trailing slash pattern matches the whole subtree).
  • If the path matches but the method does not, the mux replies 405 with an Allow header.

Precedence: the most specific pattern wins (one that matches a strict subset of requests). /items/latest beats /items/{id}. If two patterns overlap and neither is more specific (e.g. /a/{x} and /{y}/b), registration panics — conflicts are detected at startup, not at request time.

mux := http.NewServeMux()
mux.HandleFunc("GET /items/{id}", func(w http.ResponseWriter, r *http.Request) {
	fmt.Fprintf(w, "item %s", r.PathValue("id"))
})
mux.HandleFunc("GET /items/latest", latest) // more specific, wins
mux.HandleFunc("POST /items", create)
mux.HandleFunc("GET /static/{path...}", serveStatic)
mux.HandleFunc("GET /{$}", home) // only "/"

Gotcha: GODEBUG=httpmuxgo121=1 restores old behavior; wildcards must be whole segments (/b_{id} is invalid).

More on Standard Library, HTTP & Systems Design in Go

All 35 Standard Library, HTTP & Systems Design in Go questions