为了账号安全,请及时绑定邮箱和手机立即绑定

如何将一个新的 ServeMux 组合成一个更大的结构?

如何将一个新的 ServeMux 组合成一个更大的结构?

Go
守候你守候我 2021-11-08 14:35:19
在我以前使用 DefaultServeMux 制作的 golang 应用程序中,如果我有一个这样的"/users/"路由,func user(name string)例如由 处理的路由,并且我向 发送了一个请求/users/jim,该请求仍将由该"/users/"路由处理。在我正在制作的当前应用程序中,我没有使用,DefaultServeMux而只是传递一个实现 ServeHTTP 的处理程序,然后打开请求 url。但是,现在,如果我向不完全匹配的路由发送请求,则不会调用处理程序函数。例如,如果我向 发送 post 请求"/api/jim",即使"/api"已处理,我也会收到 404 错误。我想让我的应用程序保持原样(在处理程序中引用数据库),但也能够处理不完全匹配的路由。问题:假设我可以创建一个新的 ServeMux 来处理不完全匹配的路由,但是我如何将它与具有对数据库连接的引用的类型 Handler Struct 组合起来?type Handler struct{  DB *DB}func main() {    fmt.Println("Hello, playground")    db, err := sql.Open("postgres", dbinfo)    defer db.Close()    h := &Handler{      DB: db,    }    log.Fatal(http.ListenAndServe(":8888", h))}func (h *Handler)ServeHTTP(w http.ResponseWriter, r *http.Request){    switch r.URL.Path{        case "/":        h.serveRoot(w, r)        case "/api/":        h.apiRouter(w, r)    }}func (h *Handler)serveRoot(w http.ResponseWriter, r *http.Request){        h.DB.DoSomethingWithDB()}func (h *Handler)apiRouter(w http.ResponseWriter, r *http.Request){       switch r.URL.Path{           case "/":               h.serveRoot(w, r)           case "/api/":               h.apiRouter(w, r)       }}更新 由于与问题无关的原因,我不能使用 DefaultServeMux
查看完整描述

1 回答

?
ITMISS

TA贡献1871条经验 获得超8个赞

自定义处理程序结构,一个ServeMux,一个HandlerFunc和第三方路由器的所有类型http.Handler。您可以根据需要对它们进行组合和分层。


由于 ServeMux 是一个处理程序,您可以像任何其他处理程序一样将其分配给一个路径,并为各种处理程序注册单独的路径。这是使用多个的示例http.ServeMux(如果您选择,可以在单独的包中定义)。这有 3 个单独的处理程序(通过 a 定义HandlerFunc),通过 2 路由ServeMux。


这里我们在包“路由器”中创建了一个 ServeMux


var Sub = http.NewServeMux()


func subHandler(w http.ResponseWriter, r *http.Request) {

    fmt.Println("handled / in /sub")

    w.Write([]byte("/sub/\n"))

}    


func init() {

    Sub.HandleFunc("/", subHandler)

}

现在我们可以从“路由器”导入 ServeMux,并在我们的顶级处理程序中使用它,以及其他一些:


import "router"


func rootHandler(w http.ResponseWriter, r *http.Request) {

    fmt.Println("handled /")

    w.Write([]byte("/\n"))

}


func topHandler(w http.ResponseWriter, r *http.Request) {

    fmt.Println("handled /top")

    w.Write([]byte("/top/\n"))

}

func main() {


    mux := http.NewServeMux()

    mux.HandleFunc("/", rootHandler)

    mux.HandleFunc("/top/", topHandler)


    // now insert the Sub routes under "/top/sub/"

    mux.Handle("/top/sub/", http.StripPrefix("/top", router.Sub))


    server := &http.Server{Addr: ":9999", Handler: mux}

    log.Fatal(server.ListenAndServe())

}

您选择如何注册这些取决于您,通过像这样在main包中导入和路由它们,或者通过一些其他注册模式(例如database/sql驱动程序)。


也不乏 3rd 方路由包来使这更容易、更高的性能或提供更高级的模式匹配方法。


查看完整回答
反对 回复 2021-11-08
  • 1 回答
  • 0 关注
  • 146 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信