8

I'm running on HTTPS (port 10443) and use subroutes:

mainRoute := mux.NewRouter() mainRoute.StrictSlash(true) mainRoute.Handle("/", http.RedirectHandler("/static/", 302)) mainRoute.PathPrefix("/static/").Handler(http.StripPrefix("/static", *fh)) // Bind API Routes apiRoute := mainRoute.PathPrefix("/api").Subrouter() apiProductRoute := apiRoute.PathPrefix("/products").Subrouter() apiProductRoute.Handle("/", handler(listProducts)).Methods("GET") 

And the functions:

func listProducts(w http.ResponseWriter, r *http.Request) (interface{}, *handleHTTPError) { vars := mux.Vars(r) productType, ok := vars["id"] log.Println(productType) log.Println(ok) } 

ok is false and I have no idea why. I'm doing a simple ?type=model after my URL..

0

2 Answers 2

34

When you enter a URL like somedomain.com/products?type=model you're specifying a query string, not a variable.

Query strings in Go are accessed via r.URL.Query - e.g.

vals := r.URL.Query() // Returns a url.Values, which is a map[string][]string productTypes, ok := vals["type"] // Note type, not ID. ID wasn't specified anywhere. var pt string if ok { if len(productTypes) >= 1 { pt = productTypes[0] // The first `?type=model` } } 

As you can see, this can be a little clunky as it has to account for the map value being empty and for the possibility of a URL like somedomain.com/products?type=model&this=that&here=there&type=cat where a key can be specified more than once.

As per the gorilla/mux docs you can use route variables:

 // List all products, or the latest apiProductRoute.Handle("/", handler(listProducts)).Methods("GET") // List a specific product apiProductRoute.Handle("/{id}/", handler(showProduct)).Methods("GET") 

This is where you would use mux.Vars:

vars := mux.Vars(request) id := vars["id"] 

Hope that helps clarify. I'd recommend the variables approach unless you specifically need to use query strings.

Sign up to request clarification or add additional context in comments.

5 Comments

What about query parameters? @elithrar
@kamal "Query strings in Go are accessed via r.URL.Query"
There is a typo in the code it has to be if len(productTypes) >= 1
I expected mux.Vars(r) to return query parameters as well, but it does not seem to. Can anyone confirm?
@LukePighetti mux.Vars(r) returns the route variables from mux. Query parameters are returned via r.URL.Query.
4

An easier way to solve this is to add query parameters in your route through Queries, like:

apiProductRoute.Handle("/", handler(listProducts)). Queries("type","{type}").Methods("GET") 

You can get it using:

v := mux.Vars(r) type := v["type"] 

NOTE: This might not have been possible when the question was originally posted but I stumbled across this when I encountered a similar problem and the gorilla docs helped.

Comments