英文:
How can I use HttpRouter with MuxChain?
问题
我想在使用httprouter和muxchain的同时保留像/: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时,无法检索参数值,因为没有有效的方法来通过现有的函数参数传递这些值。
英文:
I'd like to use httprouter with muxchain while keeping route parameters like /:user/.
Take the following example:
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)
}
When I visit http://localhost:8080/john I obviously don't have access to ps httprouter.Params
That's because httprouter needs to see type httprouter.Handle but the function is called with type http.Handler.
Is there any way to use both packages together? The HttpRouter GitHub repo says
> The only disadvantage is, that no parameter values can be retrieved when a http.Handler or http.HandlerFunc is used, since there is no efficient way to pass the values with the existing function parameters.
答案1
得分: 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("一些日志记录器")
}
func index(res http.ResponseWriter, req *http.Request) {
	p := context.Get(req, "params").(httprouter.Params)
	fmt.Fprintf(res, "嗨,我喜欢%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)
}
希望对你有帮助!
英文:
If you strongly want to use that packages, you can try to do something like that:
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)
}
答案2
得分: 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")
            }
        }
    }
}
英文:
You would have to patch muxchain to accept httprouter.Handle, but it's rather simple to create your own chain handler, for example:
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")
			}
		}
	}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论