1 回答

TA贡献1865条经验 获得超7个赞
看来您正在尝试做两件事。1 - 仅将中间件应用于您的一些请求处理程序。2 - 将数据从您的中间件传递到您的请求处理程序。
对于第一个,我可以想到三个选项。首先是您现在正在做的事情,有一个中间件函数,当您将处理程序函数传递给r.Handle. 伪代码:
r.Handle("/path1", Mware(Handler1())).Methods("GET")
r.Handle("/path2", Mware(Handler2())).Methods("GET")
r.Handle("/path3-nomiddleware", Handler3()).Methods("GET")
您可以做的第二件事是将代码添加到中间件以根据 URI 路径进行过滤,然后使用r.Use. 伪代码:
const mwarePaths []string = ...
func Mware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.RequestURI is in mwarePaths {
// do the middleware
}
}
}
r.Use(Mware)
第三,您可以将代码放在直接在处理程序中调用的函数中,而不是像中间件一样注册它。伪代码:
func myUtil(w http.ResponseWriter, r *http.Request){ ... }
func GetAssetsCompute(assetService ServiceType) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
myUtil(w, r)
// stuff here
})
}
第二件事——将数据从中间件传递到请求处理程序——这里有一些想法。
首先,如果你使用上面的常规函数、无中间件设置,这个问题就会消失,因为你在处理程序中需要的任何东西都可以只是你函数的返回值。
如果您确实使用中间件,您可以使用该context库(也来自 gorilla)将变量绑定到 http.Request 实例以传递给您的处理程序:http ://www.gorillatoolkit.org/pkg/context 。使用它看起来像这样:
import "github.com/gorilla/context"
func middleware(...) {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
context.Set(r, "myKey", "bar")
}
}
func handler(w http.ResponseWriter, r *http.Request) {
val, ok := context.GetOk(r, "myKey") // returns "bar", true
}
您选择使用哪些选项取决于您(您知道自己的需求)。但是,正如评论中提到的,一个好的经验法则是处理与请求处理程序所做的无关问题的代码可以是中间件。处理与您的请求处理程序正在做什么直接相关的问题的代码可以直接进入处理程序。
- 1 回答
- 0 关注
- 155 浏览
添加回答
举报