How can I use HttpRouter with MuxChain?

huangapple go评论81阅读模式
英文:

How can I use HttpRouter with MuxChain?

问题

我想在使用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.Handlerhttp.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")
            }
        }
    }
}

playground

英文:

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")
			}

		}
	}
}

<kbd>playground</kbd>

huangapple
  • 本文由 发表于 2014年9月17日 18:12:44
  • 转载请务必保留本文链接:https://go.coder-hub.com/25887840.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定