从router.HandleFunc调用返回多个中间件函数

时间:2018-12-02 00:10:13

标签: go gorilla

我使用的是大猩猩/多核糖,我有这个:

router.HandleFunc("/api/v1/register",h.makeRegisterNewUser(v)).Methods("POST")

h.makeRegisterNewUser如下:

func (h Handler) makeRegisterNewUser(v interface{}) http.HandlerFunc {

    type RespBody = ...;
    type ReqBody = ...


    return func(w http.ResponseWriter, r *http.Request) {

        decoder := json.NewDecoder(r.Body)
        err := decoder.Decode(&ReqBody)

        // ...

        json.NewEncoder(w).Encode(RespBody{});
    }
}

我的问题是-是否可以从makeRegisterNewUser返回多个http.HandlerFuncs?像这样:

router.HandleFunc("/api/v1/register",h.makeRegisterNewUser(v)).Methods("POST")

func (h Handler) makeRegisterNewUser(v interface{}) (http.HandlerFunc...) {

    type RespBody = ...;
    type ReqBody = ...


    return func(w http.ResponseWriter, r *http.Request) {
       // 1

    }, func(w http.ResponseWriter, r *http.Request) {
       // 2

    }, func(w http.ResponseWriter, r *http.Request) {
        // 3
    }
}

我不确定中间件是否可以像Node.js Express中那样在Go中链接。

1 个答案:

答案 0 :(得分:1)

您可以使用包装器将多个http.Handler链接起来:

type Middleware struct {
    next          http.Handler
}

func (m Middleware) Wrap(handler http.Handler) http.Handler {
    m.next = handler
    return m
}

func (m Middleware) ServeHTTP(w http.ResponseWriter, r *http.Request) {
    // run your handler code here
    // write error into w and return if you need to interrupt request execution

    // call next handler 
    m.next.ServeHTTP(w, r)
}

注册链接的包装器和主处理程序:

h1 := Middleware{}
h2 := OtherMiddleware{}
router.Handle("/some_route", h1.Wrap(h2.Wrap(mainHandler))).Methods(http.MethodPost)

请求将执行h1h2,最后执行mainHandler

例如,您可以在h1中记录请求,在h2中进行授权,并在mainHandler中保留业务逻辑。