Search code examples
gogo-gin

Unable to call a go-gin middleware


I am learning and trying to create a simple api using go-gin framework.

I tried to create a middleware for validation but when I call it it says validations.signupValidator() is undefined.

Coming from nodejs express things seems a bit different, thanks in advance for your help

Middleware:

package validations

import (
    "github.com/bihire/ikaze_server_app/entity"
    "net/http"
    "github.com/gin-gonic/gin"
    "gopkg.in/validator.v2"
)


func signupValidator(ctx *gin.Context) {
    var user entity.User
    // if err := ctx.ShouldBindJSON(&user); err != nil {
    //    ctx.JSON(http.StatusBadRequest, gin.H{
    //        "error": err.Error(),
    //    })
    // }

    if err := validator.Validate(user); err != nil {
        ctx.JSON(http.StatusBadRequest, gin.H{
            "error": err.Error(),
        })
    }
}

calling it like

package routes

import (
    "github.com/gin-gonic/gin"
    "github.com/bihire/ikaze_server_app/service"
    "github.com/bihire/ikaze_server_app/controller"
    "github.com/bihire/ikaze_server_app/validations"
)

var (
    userController controller.UserController = controller.New(UserService)
)

func Routes(route *gin.Engine) {
    auth := route.Group("/api/auth")
    {
        
        auth.POST("login", gin.Logger(), validations.signupValidator(), func(ctx *gin.Context) {
            ctx.JSON(200, userController.Save(ctx))
        })
    }
}

Solution

  • You must first export the signupValidation since it is on another package. To do that just change to uppercase: SignupValidation

    package validations
    
    import (
        "github.com/bihire/ikaze_server_app/entity"
        "net/http"
        "github.com/gin-gonic/gin"
        "gopkg.in/validator.v2"
    )
    
    
    func SignupValidator(ctx *gin.Context) {
        var user entity.User
        // if err := ctx.ShouldBindJSON(&user); err != nil {
        //    ctx.JSON(http.StatusBadRequest, gin.H{
        //        "error": err.Error(),
        //    })
        // }
    
        if err := validator.Validate(user); err != nil {
            ctx.JSON(http.StatusBadRequest, gin.H{
                "error": err.Error(),
            })
        }
    }
    

    Second: A gin middleware is made with this signature func (ctx *gin.Context). You could do in 2 ways:

    First, if you don't want to change the Signup

    package routes
    
    import (
        "github.com/gin-gonic/gin"
        "github.com/bihire/ikaze_server_app/service"
        "github.com/bihire/ikaze_server_app/controller"
        "github.com/bihire/ikaze_server_app/validations"
    )
    
    var (
        userController controller.UserController = controller.New(UserService)
    )
    
    func Routes(route *gin.Engine) {
        auth := route.Group("/api/auth")
        {
            
            auth.POST("login", gin.Logger(), validations.SignupValidator, func(ctx *gin.Context) {
                ctx.JSON(200, userController.Save(ctx))
            })
        }
    }
    

    Or, changing Signup:

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

    Then, you can use with validations.signupValidator()

    See an example here: https://github.com/gin-gonic/gin#custom-middleware