Search code examples
gogorilla

HTTP request matching different endpoint - gorilla mux


I have the following to handler functions, DataSetsGet and RetrieveSharedData. When make request with the URL https://127.0.0.1:20000/nfdm-fdm/v2/shared-data, I get response from DataSetsGet handler instead of RetrieveSharedData handler function. When I take the bracket from {id} to id, I get the right response from RetrieveSharedData handler. Any help to solve this issue, my code below with omitted codes.

func DataSetsGet(response http.ResponseWriter, request *http.Request) {

// Data set response codes
}

func RetrieveSharedData(response http.ResponseWriter, request *http.Request) {
// Retrieve shared data response codes
}



type Route struct {
    Name        string
    Method      string
    Pattern     string
    HandlerFunc http.HandlerFunc
}

var Router = NewRouter()

type Routes []Route

func NewRouter() *mux.Router {
    router := mux.NewRouter().StrictSlash(true)
    for _, route := range routes {
        var handler http.Handler
        handler = route.HandlerFunc

        router.
            Methods(route.Method).
            Path(route.Pattern).
            Name(route.Name).
            Handler(handler)
    }

    return router
}


var routes = Routes{
    Route{
        "DataSetsGet",
        strings.ToUpper("Get"),
        "/nfdm-fdm/v2/{id}",
        DataSetsGet,
    },

    Route{
        "RetrieveSharedData",
        strings.ToUpper("Get"),
        "/nfdm-fdm/v2/shared-data",
        RetrieveSharedData,
    },

}


func main{

addr := "127.0.0.1:6060"

server := NewServer(addr)

go func() {
        err := server.ListenAndServe() 
        if err != nil && err != http.ErrServerClosed {
            logger.Log.Errorf("Could not listen on %s: %v\n", addr, err)
        }
    }()
}



// Create a new server
func NewServer(ListAddr string) *http.Server {

    return &http.Server{
        Addr:         ListAddr,
        Handler:      Router,
        ReadTimeout:  5 * time.Second,
        WriteTimeout: 10 * time.Second,
        IdleTimeout:  15 * time.Second,
    }
}



Solution

  • Just reorder your routes and make sure to include the static routes before the regex routes which would cause the static routes to take the precedence if perfectly matched before the regex routes.

    var routes = Routes{
        Route{
            "RetrieveSharedData",
            strings.ToUpper("Get"),
            "/nfdm-fdm/v2/shared-data",
            RetrieveSharedData,
        },
        Route{
            "DataSetsGet",
            strings.ToUpper("Get"),
            "/nfdm-fdm/v2/{id}",
            DataSetsGet,
        },
    }