HTTP请求匹配不同的端点 – gorilla mux

huangapple go评论88阅读模式
英文:

HTTP request matching different endpoint - gorilla mux

问题

我有以下两个处理函数:DataSetsGet和RetrieveSharedData。
当我使用URL https://127.0.0.1:20000/nfdm-fdm/v2/shared-data 发送请求时,我得到的响应是来自DataSetsGet处理函数而不是RetrieveSharedData处理函数。当我将URL中的{id}改为id时,我从RetrieveSharedData处理函数中得到了正确的响应。请帮助我解决这个问题,以下是我省略了一些代码的代码:

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)
        }
    }()
}

// 创建一个新的服务器
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,
    }
}

希望以上信息对你有帮助。

英文:

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,
}
}

答案1

得分: 0

你需要按照以下方式修复dataSetsGet函数和route handler function

func DataSetsGet(response http.ResponseWriter, request *http.Request, id string) {
    response.Write([]byte(fmt.Sprintf("myID %s", id)))
}

var routes = Routes{
    Route{
        "DataSetsGet",
        strings.ToUpper("Get"),
        "/nfdm-fdm/v2/dataset/{id}",
        func(w http.ResponseWriter, r *http.Request) {
            vars := mux.Vars(r)
            ID := strings.ToLower(vars["id"])
            DataSetsGet(w, r, ID)
        },
    },

    Route{
        "RetrieveSharedData",
        strings.ToUpper("Get"),
        "/nfdm-fdm/v2/shared-data",
        RetrieveSharedData,
    },
}
curl
curl --location --request GET 'http://localhost:6060/nfdm-fdm/v2/dataset/1234'
curl --location --request GET 'http://localhost:6060/nfdm-fdm/v2/shared-data'

我已经更改了API路径。如mkopriva建议的,使用gorilla mux无法混合使用动态和静态段。

完整的代码片段可以在playground中找到。

英文:

You will have to fix the dataSetsGet function and the route handler function as follows


func DataSetsGet(response http.ResponseWriter, request *http.Request, id string) {
        response.Write([]byte(fmt.Sprintf("myID %s", id)))
}


var routes = Routes{
        Route{
                "DataSetsGet",
                strings.ToUpper("Get"),
                "/nfdm-fdm/v2/dataset/{id}",
                func(w http.ResponseWriter, r *http.Request) {
                        vars := mux.Vars(r)
                        ID := strings.ToLower(vars["id"])
                        DataSetsGet(w, r, ID)
                },
        },

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

curl
curl --location --request GET 'http://localhost:6060/nfdm-fdm/v2/dataset/1234'
curl --location --request GET 'http://localhost:6060/nfdm-fdm/v2/shared-data'

I have changed the API path. As suggested by mkopriva, mixing dynamic and static segment is not possible with gorilla mux.

The complete code snippet can be found on playground here.

答案2

得分: 0

只需重新排序你的路由,并确保在正则表达式路由之前包含静态路由,这样如果完全匹配,则静态路由将优先于正则表达式路由。

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

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,
    },
}

huangapple
  • 本文由 发表于 2021年9月2日 20:11:39
  • 转载请务必保留本文链接:https://go.coder-hub.com/69030038.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定