Go 中的 HTTP 请求验证中间件

我正在尝试创建一个通用的 HTTP 请求验证器中间件函数,该函数接受类型(可能是 reflect.Type)作为参数,然后使用该包github.com/go-playground/validator/v10将 JSON 解组为上述类型的结构并验证该结构。我试图用下面的示例代码来解释......


例子


type LoginRequestBody struct {

   Username string `json:"username",validate:"required"`

   Password string `json:"password",validate:"required"`

}


type SignupReqBody struct {

   Username string `json:"username",validate:"required"`

   Password string `json:"password",validate:"required"`

   Age      int    `json:"age",validate:"required"`

}


// sample routers with a common middleware validator function

router.POST("/login", ReqValidate("LoginRequestBody"), LoginController)

router.POST("/signup", ReqValidate("SignupReqBody"), SignupController)


func ReqValidate(<something>) gin.HandlerFunc {

   return func (c *gin.Context) {

      // unmarshalling JSON into a struct

      // common validation logic...

      c.Next()

   }

}

总的来说,我想使用 Joi 包实现与 Node.js 中相同的验证器灵活性。


函数式编程
浏览 120回答 2
2回答

回首忆惘然

我不知道是否有必要使用中间件,但我最近尝试做一些事情,我发现了一个很棒的教程,您可以在此处查看。使用 Gin 您可以使用绑定:例子:package mainimport (&nbsp; "github.com/gin-gonic/gin"&nbsp; "net/http")type AnyStruct struct {&nbsp; &nbsp;Price uint `json:"price" binding:"required,gte=10,lte=1000"`}func main() {&nbsp; engine:=gin.New()&nbsp; engine.POST("/test", func(context *gin.Context) {&nbsp; &nbsp; &nbsp;body:=AnyStruct{}&nbsp; &nbsp; &nbsp;if err:=context.ShouldBindJSON(&body);err!=nil{&nbsp; &nbsp; &nbsp; &nbsp; context.AbortWithStatusJSON(http.StatusBadRequest,&nbsp; &nbsp; &nbsp; &nbsp; gin.H{&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "error": "VALIDATEERR-1",&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "message": "Invalid inputs. Please check your inputs"})&nbsp; &nbsp; &nbsp; &nbsp; return&nbsp; &nbsp; &nbsp;}&nbsp; &nbsp; &nbsp;context.JSON(http.StatusAccepted,&body)&nbsp; })&nbsp; engine.Run(":3000")}

郎朗坤

不要使用逗号分隔结构标签键值对,使用空格。您可以使用泛型(类型参数)来替换<something>,但您的控制器需要将具体类型作为它们的参数。例如:func ReqValidate[T any](next func(*gin.Context, *T)) gin.HandlerFunc {&nbsp; &nbsp; return func(c *gin.Context) {&nbsp; &nbsp; &nbsp; &nbsp; params := new(T)&nbsp; &nbsp; &nbsp; &nbsp; if err := c.ShouldBindJSON(params); err != nil {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; next(c, params)&nbsp; &nbsp; }}然后是控制器:type LoginRequestBody struct {&nbsp; &nbsp; Username string `json:"username" validate:"required"`&nbsp; &nbsp; Password string `json:"password" validate:"required"`}func LoginController(c *gin.Context, params *LoginRequestBody) {&nbsp; &nbsp; // ...}type SignupReqBody struct {&nbsp; &nbsp; Username string `json:"username" validate:"required"`&nbsp; &nbsp; Password string `json:"password" validate:"required"`&nbsp; &nbsp; Age&nbsp; &nbsp; &nbsp; int&nbsp; &nbsp; `json:"age" validate:"required"`}func SignupController(c *gin.Context, params *SignupReqBody) {&nbsp; &nbsp; // ...}然后是路由:router := gin.Default()router.POST("/login", ReqValidate(LoginController))router.POST("/signup", ReqValidate(SignupController))
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go