2

Trying to learn golang, and I am lost on working with the context.Request.Body and its struct in a validation middleware

briefly how do they connect to each other, thanks in advance for your help

My middleware

package validations

import (
    "github.com/bihire/ikaze_server_app/entity"
    "net/http"
    "github.com/gin-gonic/gin"
    "github.com/go-playground/validator/v10"
)


func SignupValidator(c *gin.Context) {
    // user := c.Request.Body
    var user entity.User
    validate := validator.New()
    if err := validate.Struct(&user); err != nil {
        c.JSON(http.StatusBadRequest, gin.H{
            "error": err.Error(),
        })
    }

}

My struct

package entity

type User struct {
    Username         string `json:"username" validate:"required"`
    Email            string `json:"email"  validate:"email"`
    Password         string `json:"password" validate:"min=8,max=32,alphanum"`
    ConfirmPassword  string `json:"confirm_password" validate:"eqfield=Password,required"`
}

returned response error

{
    "error": "Key: 'User.Username' Error:Field validation for 'Username' failed on the 'required' tag\nKey: 'User.Email' Error:Field validation for 'Email' failed on the 'email' tag\nKey: 'User.Password' Error:Field validation for 'Password' failed on the 'min' tag\nKey: 'User.ConfirmPassword' Error:Field validation for 'ConfirmPassword' failed on the 'required' tag"
}{
    "username": "bihire",
    "email": "hgh@gmail.com",
    "password": "password",
    "confirm_password": "password"
}

router with middleware

auth.POST("login", gin.Logger(), validations.SignupValidator, func(ctx *gin.Context) {
            ctx.JSON(200, videoController.Save(ctx))
        })
bihire boris
  • 1,530
  • 3
  • 19
  • 44

1 Answers1

5

Looks like you're missing the return:

func SignupValidator(c *gin.Context) gin.HandlerFunc {
    return func(c *gin.Context) {
       var user entity.User
       if err := c.ShouldBindJSON(&user); err == nil {           
         validate := validator.New()
         if err := validate.Struct(&user); err != nil {
              c.JSON(http.StatusBadRequest, gin.H{
                 "error": err.Error(),
          })
          c.Abort()
          return
         }
       }
       c.Next()
    }
}

Note that we call c.Abort() if the validation failed. This is because gin calls the next function in the chain even after you write the header (c.JSON()) using c.Next().

Roman Kiselenko
  • 43,210
  • 9
  • 91
  • 103
  • Now it is saying too many arguments to return though, do you know what that is about? – bihire boris Jul 04 '20 at 12:43
  • that actually works, but I am still getting the error in the question. How do I pass data in that middleware. error `"error": "Key: 'User.Username' Error:Field validation for 'Username' failed on the 'required' tag\nKey: 'User.Email' Error:Field validation for 'Email' failed on the 'email' tag\nKey: 'User.Password' Error:Field validation for 'Password' failed on the 'min' tag\nKey: 'User.ConfirmPassword' Error:Field validation for 'ConfirmPassword' failed on the 'required' tag"` – bihire boris Jul 04 '20 at 12:49
  • 1
    This is because you're passing an empty structure to the validator. `var user entity.User` is an empty structure. – Roman Kiselenko Jul 04 '20 at 12:50
  • sure I noticed that, how do I pass data through that structure thought, apologies if it sounds dumb I am still learning – bihire boris Jul 04 '20 at 12:54