Go Gorilla Mux 没有按预期路由

Go Gorilla Mux not routing as expected

我在获取用于 Go 的 Gorilla Mux 库时遇到问题。从我阅读的文档和我所做的所有调试中,我似乎无法弄清楚问题是什么。这是我的路由:

文件夹结构:

project_root
  |-- main.go
  |-- routes
         |-- routes.go
         |-- user.go

main.go:

package main

import (
    "fmt"
    "net/http"

    "./routes"
)

func main() {
    r := routes.CreateRoutes(http.Dir("./content"))

    http.Handle("/", r)
    err := http.ListenAndServe(fmt.Sprintf("%s:%d", "localhost", 8000), nil)
    if err != nil {
        fmt.Println("Error: ", err)
    }
}

routes/routes.go

package routes

import (
    "net/http"

    "github.com/gorilla/mux"
)

func CreateRoutes(staticDir http.FileSystem) *mux.Router {
    r := mux.NewRouter()

    // Serve static pages (i.e. web app)
    r.PathPrefix("/").Handler(http.FileServer(staticDir))

    // Serve User Pages
    createUserRoutes(r)

    return r
}

routes/user.go

package routes

import (
    "fmt"
    "net/http"

    "github.com/gorilla/mux"
)

func createUserRoutes(r *mux.Router) {
    user := r.PathPrefix("/user/").Subrouter()

    // Create a new user
    user.Path("/new").Methods("PUT").HandlerFunc(newUserHandler)

    // Remove a user
    user.Path("/remove/{username:[a-z][a-z0-9]+}").Methods("DELETE").HandlerFunc(removeUserHandler)

    // Update a user
    user.Path("update/{username:[a-z][a-z0-9]+").Methods("POST").HandlerFunc(updateUserHandler)

    // Get a user (Get user information)
    user.Path("/{username:[a-z][a-z0-9]+").Methods("GET").HandlerFunc(getUserHandler)
}

func newUserHandler(resp http.ResponseWriter, req *http.Request) {
    // Do something that might cause an error        

    if err != nil {
        fmt.Println(err)
        resp.WriteHeader(409)
        resp.Write([]byte(err.Error()))
    } else {
        fmt.Println("Created new user")
        resp.WriteHeader(201)
        resp.Write([]byte("Created new user"))
    }
}

func removeUserHandler(resp http.ResponseWriter, req *http.Request) {
}

func updateUserHandler(resp http.ResponseWriter, req *http.Request) {
}

func getUserHandler(resp http.ResponseWriter, req *http.Request) {
}

每当我向服务器的根路径(即提供静态内容的路径)发出请求时,服务器都会按预期响应,并显示主页。但是,任何其他调用都会导致 404 响应(我使用 cURL 测试请求)。例如,对 http://localhost:8000/user/new 的格式错误的请求应该 return 是 409,但 return 是 404。如果我期望 201 响应也是如此。

一切正常,我已经检查了三次,但我无法弄清楚这里的问题是什么。

事实证明,解决方案很简单(通常如此)。 routes.go

中的这一行
r.PathPrefix("/").Handler(http.FileServer(staticDir))

导致了意外路由。使用 PathPrefix 时,它似乎将所有 URL 路由到第一个匹配的前缀(在本例中为此前缀)。这解释了为什么静态文件被提供,但没有其他工作。

解决方法是改用 Path 函数 。如文档中所述,存在细微差别; PathPrefix "matches if the given template is a prefix of the full URL path",而 Path 则没有。因此,上面的行现在看起来像这样来解决我遇到的问题:

r.Path("/").Handler(http.FileServer(staticDir))