Description
Proposal Details
Go 1.22 has provided http.ServeMux
with supporting of pattern match for requests. While I'm using it, I tried to get the matched pattern of that request. With help of *ServeMux.Handler
, I can successfully get matched handler and pattern, but later when I run debug of the code, I found in *http.Request
itself, there is a private pat
which is exactly matched pattern info. I suggest we export the pat
for public access or provide some function to allow user to get the matched pattern, so that we can avoid much logic to use *ServeMux.Handler
to parse the request again. This reduces huge resource usage in high load services.
The matched pattern info is usually very useful when we do analysis for requests. We can group requests by their pattern and make the analysis more generic. This is a very high frequency usage scenario which makes reducing the resource usage very worthy.
sample code:
func TestServeMux(t *testing.T) {
m := http.NewServeMux()
m.Handle("GET /{name}", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
t.Log(r.PathValue("name"))
}))
http.ListenAndServe(":8999", m)
}
When we do request GET http://127.0.0.1:8999/aloha
, we can see such info in debug console.

Update 2024/03/28:
As we talked in comments, @jba 's suggestion is a good solution #66405 (comment)
// Pattern returns the pattern that matched this request, if the request
// resulted from matching a pattern registered on a ServeMux.
// Otherwise, it returns the empty string.
func (*Request) Pattern() string
Update 2024/04/11:
After many discussions, the latest proposal can be found here #66405 (comment)
In short, add a Pattern
field in http.Request
to expose matched pattern info and can be set by third party routers.
Update 2024/05/13:
Final design: #66405 (comment)
The proposal is to add a Pattern string field to net/http.Request.
ServeMux.ServeHTTP will set the field to the pattern of the matching handler before dispatching to that handler when using the new Go 1.22 HTTP mux.
In Go 1.21 compatibility mode the field is unset.
The field is otherwise left untouched. Third-party routers may set it if they wish.