首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在goLang中使用julienschmidt/httprouter时使用中间件?

如何在goLang中使用julienschmidt/httprouter时使用中间件?
EN

Stack Overflow用户
提问于 2017-05-14 13:31:25
回答 2查看 6.3K关注 0票数 4

在使用julienschmidt/httprouter时,链接中间件的最佳方法是什么?

据我搜索,http.HandlerFunc只接受表单func (w ResponseWriter, r *Request)中的函数,而httprouter.Handle函数是表单func (w http.ResponseWriter, r *http.Request, ps httprouter.Params)

如何在不将httprouter.Handle函数转换为http.HandlerFunc的情况下链接中间件?

例如:

我的routes.go是表格的,

代码语言:javascript
复制
router  :=  httprouter.New()
router.POST("/api/user/create", middlewares.EscapeStringsMiddleware(User.CreateUser))
log.Fatal(http.ListenAndServe(":8000",  router))

如何为上述路由编写中间件功能?

已经尝试过的方法:

1.

代码语言:javascript
复制
func EscapeStringsMiddleware(next http.Handler) httprouter.Handle {

    return func (response http.ResponseWriter, request *http.Request, ps httprouter.Params) {
        err := request.ParseForm()
        if err != nil {
            panic(err)
        }

        for key, values := range request.Form {
            for i, value := range values {
                value = template.HTMLEscapeString(value)
                value = template.JSEscapeString(value)
                request.Form[key][i] = value
            }
        }
        next.ServeHTTP(response, request)
    }
}

获得误差:

代码语言:javascript
复制
cannot use User.CreateUser (type func(http.ResponseWriter, *http.Request, httprouter.Params)) as type http.Handler in argument to middlewares.EscapeStringsMiddleware:
func(http.ResponseWriter, *http.Request, httprouter.Params) does not implement http.Handler (missing ServeHTTP method)

2.

代码语言:javascript
复制
func EscapeStringsMiddleware(next httprouter.Handle) httprouter.Handle {

    return func (response http.ResponseWriter, request *http.Request, ps httprouter.Params) {
        err := request.ParseForm()
        if err != nil {
            panic(err)
        }

        for key, values := range request.Form {
            for i, value := range values {
                value = template.HTMLEscapeString(value)
                value = template.JSEscapeString(value)
                request.Form[key][i] = value
            }
        }
        next.ServeHTTP(response, request)
    }
}

获得误差:

代码语言:javascript
复制
next.ServeHTTP undefined (type httprouter.Handle has no field or method ServeHTTP)

另外,我如何链接多个中间件?

例如,

代码语言:javascript
复制
router.POST("/api/user/create", middlewares.VerifyCSRF(middlewares.EscapeStringsMiddleware(User.CreateUser)))
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-05-14 13:43:01

此问题与您的中间件处理程序无关。您正在接受错误,因为User.CreateUser不是http.Handler类型的。

尝试以下模式:

重要的一点是返回一个http.Handler并用http.HandlerFunc包装func(w http.ResponseWriter, r *http.Request)

代码语言:javascript
复制
func Handler() http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        // do stuff
    })
}

消息来源:

代码语言:javascript
复制
// The HandlerFunc type is an adapter to allow the use of
// ordinary functions as HTTP handlers. If f is a function
// with the appropriate signature, HandlerFunc(f) is a
// Handler that calls f.
type HandlerFunc func(ResponseWriter, *Request)

// ServeHTTP calls f(w, r).
func (f HandlerFunc) ServeHTTP(w ResponseWriter, r *Request) {
    f(w, r)
}

根据你的反馈:

httprouter.Handle不实现ServeHTTP。它被直接称为。例如:next(w, r, ps)

下面将找到中间件处理程序的示例。

代码语言:javascript
复制
// Middleware without "github.com/julienschmidt/httprouter"
func StdToStdMiddleware(next http.Handler) http.Handler {

    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        // do stuff
        next.ServeHTTP(w, r)
    })
}

// Middleware for a standard handler returning a "github.com/julienschmidt/httprouter" Handle
func StdToJulienMiddleware(next http.Handler) httprouter.Handle {

    return func(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
        // do stuff
        next.ServeHTTP(w, r)
    }
}

// Pure "github.com/julienschmidt/httprouter" middleware
func JulienToJulienMiddleware(next httprouter.Handle) httprouter.Handle {

    return func(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
        // do stuff
        next(w, r, ps)
    }
}

func JulienHandler() httprouter.Handle {
    return func(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
        // do stuff
    }
}

func StdHandler() http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        // do stuff
    })
}

func main() {
    router := httprouter.New()
    router.POST("/api/user/create", StdToJulienMiddleware(StdHandler()))
    router.GET("/api/user/create", JulienToJulienMiddleware(JulienHandler()))
    log.Fatal(http.ListenAndServe(":8000", router))
}
票数 17
EN

Stack Overflow用户

发布于 2017-12-10 17:08:58

https://github.com/cnvrtly/adaptr库中,适配器也被添加到链请求中间件函数中。

代码语言:javascript
复制
func compatibleHandler(h http.Handler, httprParamsCtxKey interface{}) httprouter.Handle {
return toHttpRouterHandle(h, httprParamsCtxKey)
}
func toHttpRouterHandle(h http.Handler, httprParamsCtxKey interface{}) func(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
   return func(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
    if httprParamsCtxKey != nil {
        r = SetCtxValue(r, httprParamsCtxKey, p)
    }
    h.ServeHTTP(w, r)
   }
}

如果您正在寻找如何定义路由的示例/想法:https://github.com/cnvrtly/golang-appengine-seed

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/43964461

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档