如何将HttpRouter与MuxChain一起使用?

时间:2014-09-17 10:12:44

标签: go

我希望httproutermuxchain一起使用,同时保留/:user/等路线参数。

采用以下示例:

func log(res http.ResponseWriter, req *http.Request) {
  fmt.Println("some logger")
}

func index(res http.ResponseWriter, req *http.Request) {
  fmt.Fprintf(res, "Hi there, I love %s!", req.URL.Path[1:])
}

func main() {
  logHandler := http.HandlerFunc(log)
  indexHandler := http.HandlerFunc(index)
  chain := muxchain.ChainHandlers(logHandler, indexHandler)
  router := httprouter.New()
  router.Handler("GET", "/:user", chain)
  http.ListenAndServe(":8080", router)
}

当我访问http://localhost:8080/john时,我显然无法访问ps httprouter.Params 那是因为httprouter需要看到类型httprouter.Handle,但是使用类型http.Handler调用该函数。

有没有办法同时使用这两个包? HttpRouter GitHub回购说

  

唯一的缺点是,当使用http.Handler或http.HandlerFunc时,无法检索任何参数值,因为没有有效的方法可以使用现有的函数参数传递值。

2 个答案:

答案 0 :(得分:4)

如果您非常想使用该软件包,可以尝试执行以下操作:

package main

import (
    "fmt"
    "github.com/gorilla/context"
    "github.com/julienschmidt/httprouter"
    "github.com/stephens2424/muxchain"
    "net/http"
)

func log(res http.ResponseWriter, req *http.Request) {
    fmt.Printf("some logger")
}

func index(res http.ResponseWriter, req *http.Request) {
    p := context.Get(req, "params").(httprouter.Params)
    fmt.Fprintf(res, "Hi there, I love %s!", p.ByName("user"))
}

func MyContextHandler(h http.Handler) httprouter.Handle {
    return func(res http.ResponseWriter, req *http.Request, p httprouter.Params) {
        context.Set(req, "params", p)
        h.ServeHTTP(res, req)
    }
}

func main() {
    logHandler := http.HandlerFunc(log)
    indexHandler := http.HandlerFunc(index)
    chain := muxchain.ChainHandlers(logHandler, indexHandler)
    router := httprouter.New()
    router.GET("/:user", MyContextHandler(chain))
    http.ListenAndServe(":8080", router)
}

答案 1 :(得分:3)

您必须修补muxchain以接受httprouter.Handle,但创建自己的链处理程序相当简单,例如:

func chain(funcs ...interface{}) httprouter.Handle {
    return func(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
        for _, h := range funcs {
            switch h := h.(type) {
            case httprouter.Handle:
                h(w, r, p)
            case http.Handler:
                h.ServeHTTP(w, r)
            case func(http.ResponseWriter, *http.Request):
                h(w, r)
            default:
                panic("wth")
            }

        }
    }
}

playground