我正在构建一个Go web应用程序,它在处理路由时支持各种中间件功能。我试图尽可能多地坚持使用net/http,并想知道如何不用像negroni这样的中间件库来完成这个任务。
本质上,我想要做的是能够提供中间件功能的一部分,比如一个用于日志记录,一个用于检查有效的JWT,最后是处理处理程序来处理请求。
通过定义以下结构,我就可以使用negroni相当简单地完成这一任务:
// Route ..
type Route struct {
Method string
Path string
Middleware []negroni.Handler
Handler http.HandlerFunc
}然后定义一条路线,如:
var commonRoutes = []Route{
{
Method: "GET",
Path: "/info",
Middleware: []negroni.Handler{negroni.HandlerFunc(middleware.CheckCache), negroni.HandlerFunc(middleware.Authenticated), negroni.NewLogger()},
Handler: handlers.APIInfo,
},
}最后,当我启动服务器时,我导入路由列表并按如下方式注册它们:
for _, r := range routes {
handler := append(r.Middleware, negroni.Wrap(r.Handler))
router.Handle(r.Path, negroni.New(handler...)).Methods(r.Method)
}这件事做得很好。
如果我知道如何使用标准的net/http签名和定义如下所示的中间件处理程序的方式,就可以做到这一点:
http.Handle("/", middlewareOne(middlewareTwo(finalHandler)))谢谢您:)
发布于 2017-09-19 07:25:20
func Auth(n http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
log.Printf("Start")
n.ServeHTTP(w, r)
log.Printf("End")
})
}
func processReq(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("Success"))
}
func main() {
handler := http.HandlerFunc(processReq)
http.Handle("/",Auth(handler))
http.ListenAndServe(":8000", nil)
}可以使用http.handler完成
发布于 2017-09-19 07:40:08
很简单。您可以这样定义每个处理程序:
// So I don't have to type it over and over...
type HTTPHandler func(w http.ResponseWriter, r *http.Request)
func Handler1(next HTTPHandler) HTTPHandler {
return func(w http.ResponseWriter, r *http.Request){
// Do stuff
if next != nil {
next(w, r)
}
}
}
// Handler2 ... HandlerN defined in the same basic way.
// Chaining:
http.Handle("/", Handler1(Handler2(nil)))每个处理程序接受下一个处理程序,并返回一个闭包,该闭包可以执行任何您想要的操作,并调用下一个处理程序。如果您需要大量这样的工具,那么编写一个类似于此的助手可能是有意义的:
func MakeHandler(worker, next HTTPHandler) HTTPHandler {
return func(w http.ResponseWriter, r *http.Request){
// Maybe have to worker return an error and do standard error
// handling here? Could simplify your code some depending on
// what you are doing.
worker(w, r)
if next != nil {
next(w, r)
}
}
}https://stackoverflow.com/questions/46292705
复制相似问题