Sure you can. The ServeMux is an http.Handler.
package main
import (
"fmt"
"net/http"
)
func main() {
apiMux := http.NewServeMux()
apiMux.HandleFunc("/test", handleAPITest)
usersMux := http.NewServeMux()
usersMux.HandleFunc("/test", handleUsersTest)
topMux := http.NewServeMux()
topMux.Handle("/api/", http.StripPrefix("/api", apiMux))
topMux.Handle("/users/", http.StripPrefix("/users", usersMux))
http.ListenAndServe(":1234", topMux)
}
func handleAPITest(w http.ResponseWriter, req *http.Request) {
// Called for /api/test
fmt.Fprintf(w, "Hello from /api/test\n")
}
func handleUsersTest(w http.ResponseWriter, req *http.Request) {
// Called for /users/test
fmt.Fprintf(w, "Hello from /users/test\n")
}
Note the http.StripPrefix
so that the two second level muxes don’t need to know where they’re “rooted”.
Edit: I noticed I didn’t implement exactly what you asked, but I think you can see the method of combining muxes with prefixes at least.