为了账号安全,请及时绑定邮箱和手机立即绑定

gorilla mux 中间件:包装处理程序

gorilla mux 中间件:包装处理程序

Go
慕哥6287543 2022-06-01 17:44:45
我需要将GetAssetsCompute函数包装在中间件中r.Handle("/api/v1/assets/ComputeBlade", GetAssetsCompute(assetService)).Methods("GET")func GetAssetsCompute(assetService ServiceType) http.Handler {    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {        //  stuff here    })}但是因为中间件将 HTTP 处理程序作为参数,而我的函数不是处理程序,所以我不能。我正在考虑做这样的事情。func GetAssetsCompute(assetService ServiceType) http.Handler {        return MyMiddleware(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {            //  stuff here        }))    }func MyMiddleware(next http.Handler) http.Handler {}这个对吗?或者有没有更好的方法来做到这一点。同样在中间件内部,我需要访问 URL 端点,进行一些处理并存储这个处理后的值,然后再次在主处理程序中访问它。我怎样才能做到这一点?编辑:我想将此中间件仅应用于我拥有的端点的子集(> 1)。不是全部我还需要处理程序中函数中assetService使用的变量。GetAssetsCompute(assetService ServiceType)所以,我也需要这个闭包。
查看完整描述

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

}


您选择使用哪些选项取决于您(您知道自己的需求)。但是,正如评论中提到的,一个好的经验法则是处理与请求处理程序所做的无关问题的代码可以是中间件。处理与您的请求处理程序正在做什么直接相关的问题的代码可以直接进入处理程序。


查看完整回答
反对 回复 2022-06-01
  • 1 回答
  • 0 关注
  • 155 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号