微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

在中间件中绑定查询

如何解决在中间件中绑定查询

我正在尝试编写一个“Binder”中间件,它将使用带有 gin 绑定/验证器的结构类型来验证任何请求查询

例如,假设我有一个名为 /api/subject 的端点组,它要求查询字符串具有一个主题代码一个 ID,该 ID 将使用以下结构(称为 entity.Subject)进行验证:

type Subject struct {
    Code string `binding:"required,alphanum"`
    ID   string `binding:"required,alphanum,len=4"`
}

这只是一个例子,但我希望能够将任何结构类型传递给这个中间件,因为我希望在未来的处理程序上访问查询数据而不必担心查询验证。

所以我尝试了这样的事情:

func Binder(t reflect.Type) gin.HandlerFunc {
    return func(c *gin.Context) {
        obj := reflect.New(t).Elem().Interface()
        if err := c.BindQuery(&obj); err != nil {
            c.AbortWithStatus(http.StatusBadRequest)
            return
        }

        c.Set(t.Name(),obj)
    }
}

并像这样添加了这个中间件:

apiGroup := router.Group("/api")
{
    // other subgroups/endpoints
    // ...
    subjectGroup := apiGroup.Group("/subject",middleware.Binder(reflect.TypeOf(entity.Subject{})))
}

然后,在另一个处理函数中,假设 GetSubject,我想访问通过执行 c.MustGet("Subject").(entity.Subject) 传递的主题数据

但这不起作用 =(,当我打印 obj 时,它只是一个空界面,我该怎么做?

解决方法

我设法做了类似的事情!

我创建了以下中间件

jQuery('.collapse').on('show.bs.collapse',function () {
        jQuery('.collapse').removeClass('in');    
});

记得在调用中传递一个指向你想要的类型的指针,就像这样:

var allowedTypes = []binding.Binding{ binding.Query,binding.Form,binding.FormPost,binding.FormMultipart,} func Bind(name string,data interface{},bindingType binding.Binding) gin.HandlerFunc { return func(ctx *gin.Context) { ok := false for _,b := range allowedTypes { if b == bindingType { ok = true } } if !ok { ctx.AbortWithError( http.StatusInternalServerError,fmt.Errorf("Bind function only allows %v\n",allowedTypes),) } _ = ctx.MustBindWith(data,bindingType) ctx.Set(name,data) } }

我只限制了几种绑定类型,因为它们允许多次调用 router.GET("/something",Bind("Object",&myObject,binding.Query)),而 ShouldBindJSON 和其他类型使用 XML 主体。>

通过这种方式,您可以传递多个 Bind 中间件,如果验证失败,它会自动中止 Request

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。