在Golang HTTP或Gorilla包中获取路由和参数列表

When I write a simple web application like this:

func handler(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintf(w, "Hi there, I love %s!", r.URL.Path[1:])
}

func main() {
    http.HandleFunc("/about", handler)
    http.ListenAndServe(":8080", nil)
}

How can I find the list of routes and params which I defined in my web app? e.g find "/about" in this example.

EDIT 1: How can get this one params and route?

gorilla.HandleFunc(`/check/{id:[0-9]+}`, func(res http.ResponseWriter, req *http.Request) {
    res.Write([]byte("Regexp works :)"))
})

You could use http.DefaultServeMux (type ServeMux) and examine it. With reflect package you can ValueOf the default multiplexer and extract m attribute which is a map of your routes.

v := reflect.ValueOf(http.DefaultServeMux).Elem()
fmt.Printf("routes: %v
", v.FieldByName("m"))

upd:

if you use net/http than you should implement extracting params before any request is actually done by yourself; otherwise you have access to params with r.URL.Query()

if you use gorilla/mux than as elithrar mentioned you should use Walk:

func main:

r := mux.NewRouter()
r.HandleFunc("/path/{param1}", handler)

err := r.Walk(gorillaWalkFn)
if err != nil {
    log.Fatal(err)
}

func gorillaWalkFn:

func gorillaWalkFn(route *mux.Route, router *mux.Router, ancestors []*mux.Route) error {
    path, err := route.GetPathTemplate()
    return nil
}

the path variable contains your template:

"/path/{param1}"

but you should extract params manually.

You can see list of routes in HTTP package.

http.HandleFunc("/favicon.ico", func(res http.ResponseWriter, req *http.Request) {
    http.ServeFile(res, req, "favicon.ico")
})
http.HandleFunc(`/check`, func(res http.ResponseWriter, req *http.Request) {
    res.Write([]byte("Regexp works :)"))
})

httpMux := reflect.ValueOf(http.DefaultServeMux).Elem()
finList := httpMux.FieldByIndex([]int{1})
fmt.Println(finList)

An answer to improve i guess.

it provides the missing piece of code to extract parameters from the route path template string.


var pathTemplateRegex = regexp.MustCompile(`\{(\\?[^}])+\}`)

func getRouteParams(router *mux.Router, route string) []string {
    r := router.Get(route)
    if r == nil {
        return nil
    }
    t, _ := r.GetPathTemplate()
    params := pathTemplateRegex.FindAllString(t, -1)
    for i, p := range params {
        p = strings.TrimPrefix(p, "{")
        p = strings.TrimSuffix(p, "}")
        if strings.ContainsAny(p, ":") {
            p = strings.Split(p, ":")[0]
        }
        params[i] = p
    }
    return params
}