2015-08-26 60 views
3

對我的應用程序的每個請求都應該使用一些中間件。使用內格羅尼文檔我已經實現了它,像這樣:將參數傳遞給Negroni中間件

func MyMiddleware(rw http.ResponseWriter, r *http.Request, next http.HandlerFunc) { 
    // do some stuff before 
    next(rw, r) 
} 

和其他地方使用:

n.Use(negroni.HandlerFunc(MyMiddleware)) 

然而,中間件需要接受額外的參數,我不知道如何建立這個英寸現在,我只是將該值設置爲全局變量以使其可用,但我確定有一種更優雅的方式?

我希望能夠做這樣的事情:

n.Use(negroni.HandlerFunc(MyMiddleware(val))) 

回答

3

最好的辦法是封裝中間件爲保持其狀態,不只是一個無狀態的功能的結構。 (你也可以把它包裝成一個封閉但結構是清潔IMO):

type MyMiddleware struct { 
    someval string 
} 

func NewMyMiddleware(someval string) *MyMiddleware { 
    return &MyMiddleware{ 
     someval: someval, 
    } 
} 


func (m *MyMiddleware) ServeHTTP(w http.ResponseWriter, r *http.Request, next http.HandlerFunc) { 

    // Do Something with someval 
    fmt.Println(m.someval) 

    next(w, req) 
} 

和初始化工作很簡單:

n.Use(NewMyMiddleware("foo")) 

編輯:也許一個封蓋實際上很簡單:

someval := foo 

n.Use(negroni.HandlerFunc(func(rw http.ResponseWriter, r *http.Request, next http.HandlerFunc) { 
    // Do Something with someval 
    fmt.Println(someval) 

    next(w, req) 
})) 

或者你可以有一個返回中間件功能的函數:

func NewMiddleware(someval string) negroni.HandlerFunc { 
    return negroni.HandlerFunc(func(rw http.ResponseWriter, r *http.Request, next http.HandlerFunc) { 
     // Do Something with someval 
     fmt.Println(someval) 

     next(w, req) 
    }) 
} 

然後

n.Use(NewMiddleware("foo")) 
+0

嗯 - 好像有點小題大做,我 - 可能與全局變量堅持說實話。 – tommyd456

+1

@ tommyd456,直到您需要多個有狀態變量,或者您需要多箇中間件實例。如果既不是這樣,那麼關閉就足夠了。我會將其添加到我的答案。 –

+0

我喜歡封閉的方法 - 我給了我一個自己去,幾乎在那裏。爲此歡呼。早上要去吧! – tommyd456