Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Gorilla Mux Subroute Methods POST request trigger GET

Tags:

go

gorilla

I'm trying to develop a simple REST API in Go, using Gorilla Mux.

I have the main.go which register the simple path above and start the server to listen on port 3000.

func main() {
    router := mux.NewRouter().StrictSlash(true)
    sub := router.PathPrefix("/api/v1").Subrouter()
    handlers.RegisterRoutes(sub)

    log.Fatal(http.ListenAndServe(":3000", router))
}

A basic handlers registration method inside another generic handlers.go file

func RegisterRoutes(sub *mux.Router) {
    user.RegisterRoutes(sub)
}

And the user.handler.go file, which register the "/user" subroute:

func RegisterRoutes(sub *mux.Router) {
    userRoutes := sub.StrictSlash(true).Path("/users").Subrouter()

    userRoutes.Methods("POST").HandlerFunc(getUsers)
    userRoutes.Methods("GET").HandlerFunc(getUsers)
}

func getUsers(w http.ResponseWriter, r *http.Request) {
    user := User{Name: "test", Password: "test"}

    fmt.Printf("%+v\n", r.Method)

    json.NewEncoder(w).Encode(user)
}

I was testing the path that I've had set up above, and came up with an wird behavior:

Test - GET - localhost:3000/api/v1/users  => Prints GET in console. (as expected)
Test - GET - localhost:3000/api/v1/users/  => Prints GET in console. (as expected)
Test - POST - localhost:3000/api/v1/users  => Prints POST in console. (as expected)
Test - POST - localhost:3000/api/v1/users/  => Prints GET in console. (And here is the strange behavior)

When I send a POST to the endpoint(localhost:3000/api/users/) with the trailing slash at the end of the url it triggers the GET instead of the POST.

Anyone came across with this behavior using Gorilla Mux?

like image 959
Leonardo Fachini Martins Avatar asked Oct 30 '22 01:10

Leonardo Fachini Martins


1 Answers

The specific issue would be mux issue 79, which is still pending (even if closed), also seen in mux issue 254

That seems also related to mux issue 145: StrictSlash is confusing

This

"When true, if the route path is "/path/", accessing "/path" will redirect to the former and vice versa. In other words, your application will always see the path as specified in the route."

and

"When false, if the route path is "/path", accessing "/path/" will not match this route and vice versa."

should be inverted, because strict==true should mean no trailing slash allowed.
It's name and docs are confusing.

like image 52
VonC Avatar answered Nov 22 '22 23:11

VonC