【发布时间】:2018-02-05 16:57:48
【问题描述】:
我有一个 golang api 应用程序。我已经定义了一组路由和处理程序。但是,多路复用路由器只返回最后一条路由。
当我请求 /api/info 时,我在日志中得到了这个:
9:0:38 app | 2018/02/05 09:00:38 GET /api/info Users Create 308.132µs
为什么路由到错误的路由?
路由包:
// NewRouter establishes the root application router
func NewRouter(context *config.ApplicationContext, routes Routes, notFoundHandler http.HandlerFunc) *mux.Router {
router := mux.NewRouter()
router.NotFoundHandler = notFoundHandler
for _, route := range routes {
router.
PathPrefix("/api").
Methods(route.Method).
Path(route.Pattern).
Name(route.Name).
// TODO: fix HandlerFunc. Right now, it is overriding previous routes and setting a single handler for all
// this means that the last route is the only router with a handler
HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
logRoute(setJSONHeader(route.HandlerFunc), route.Name)(context, w, r)
})
}
return router
}
func logRoute(inner ContextHandlerFunc, name string) ContextHandlerFunc {
return func(c *config.ApplicationContext, w http.ResponseWriter, r *http.Request) {
start := time.Now()
inner(c, w, r)
log.Printf(
"%s\t%s\t%s\t%s",
r.Method,
r.RequestURI,
name,
time.Since(start),
)
}
}
func setJSONHeader(inner ContextHandlerFunc) ContextHandlerFunc {
return func(c *config.ApplicationContext, w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
inner(c, w, r)
}
}
主包:
var context = config.ApplicationContext{
Database: database.NewDatabase().Store,
}
var routes = router.Routes{
router.Route{"Info", "GET", "/info", handlers.InfoShow},
router.Route{"Users Create", "POST", "/users/create", handlers.UsersCreate},
}
func main() {
notFoundHandler := handlers.Errors404
router := router.NewRouter(&context, routes, notFoundHandler)
port := os.Getenv("PORT")
log.Fatal(http.ListenAndServe(":"+port, router))
}
如果我访问/api/info,它将尝试向/users/create 调用POST。但是,如果我删除第二条路由,它将正确路由到 InfoShow 处理程序。
为什么 mux 会覆盖第一条路由?我很确定
HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
logRoute(setJSONHeader(route.HandlerFunc), route.Name)(context, w, r)
})
但我不确定为什么会导致它映射到第一条路线。
想法?
【问题讨论】:
-
请说明您使用的是什么
mux包。 -
@leafbebop 我正在使用最新的github.com/gorilla/mux
-
不相关,但这是一种糟糕的做法:
router := router.NewRouter(&context, routes, notFoundHandler)。您正在使用router变量隐藏router包。以不同的方式命名它们。作为一个实践问题,建议不要以某人自然会从该包中命名该类型的名称来命名您的包。使用您在 OP 中指定的routing名称而不是路由器。将减少混乱的代码。 -
谢谢。 golang 新手。那是无意的,我将重命名它。我要做的就是将数据库传递给处理程序。 Go 迫使我将所有内容分成多个包,但从根本上说,这些部分是一个单独的包,所以我很难找到一个好的结构。
-
如果需要,您可以将它们全部放在同一个包中。将它们分开可能是一种很好的做法,因为它可以让您更好地隔离关注点,但是在 Go 中没有什么强制您将代码分成包,除非您希望获得单独命名空间的文档优势。跨度>