bube054 / ginvalidator

A Gin middleware for validating requests, similar to the nodejs package github.com/express-validator/express-validator
MIT License
5 stars 1 forks source link

Question #6

Open jihadismail8 opened 2 days ago

jihadismail8 commented 2 days ago

how to combine multi validations in one route ? i have this route

g.POST("/", Validators.Name(),Validators.IpAddress(), h.Create) i would like instead of calling multiple functions for the route , i want to make one function that would call them all . like this

    g.POST("/", Validators.AllforCreateRoute(), h.Create) // [post] /api/v1/devices

func Name() gin.HandlerFunc {
    return gv.NewBody("Name", func(initialValue, sanitizedValue, validatorName string) string {
        return "Please enter Name"
    }).Chain().Not().Empty(nil).Trim("").Validate()
}

func IpAddress() gin.HandlerFunc {
    return gv.NewBody("iPAddress", func(initialValue, sanitizedValue, validatorName string) string {
        switch validatorName {
        case gv.CustomValidatorName:
            return "iPAddress already exists."
        case gv.IPValidatorName:
            return "Please enter iPAddress or IP address is not valid."
        default:
            return gv.DefaultValChainErrMsg
        }
    }).Chain().Not().Empty(nil).
        IP("").
        CustomValidator(
            func(req *http.Request, initialValue, sanitizedValue string) bool {
                var exists bool
                var wg sync.WaitGroup
                wg.Add(1)

                go func() {
                    defer wg.Done()
                    exists = isDevicePresent(sanitizedValue)
                }()

                wg.Wait()

                return !exists
            },
        ).
        Validate()
}

func AllforCreateRoute() gin.HandlerFunc {
     Name()
     IpAddress()
}

so how to do that ? any idea , could not find anything in docs , but this is useful , because i could use for example the Name validator in another route or something

bube054 commented 1 day ago

You can combine multiple validators in a single route using the append function and variadic arguments.

package main

import (
    "net/http"

    gv "github.com/bube054/ginvalidator"
    "github.com/gin-gonic/gin"
)

func main() {
    r := gin.Default()

    createEmailValidator := func() gin.HandlerFunc {
        return gv.NewBody("email", nil).Chain().Email(nil).Validate()
    }

    createNameValidator := func() gin.HandlerFunc {
        return gv.NewBody("name", nil).Chain().Not().Empty(nil).Validate()
    }

    combineValidators := func() []gin.HandlerFunc {
        return []gin.HandlerFunc{
            createEmailValidator(),
            createNameValidator(),
        }
    }

    r.GET("/hello", append(combineValidators(), func(ctx *gin.Context) {
        ctx.JSON(http.StatusOK, gin.H{
            "message": "Hello World!",
        })
    })...)

    r.Run()
}

Well though it works, the above code is not idiomatic go code. With this technique you should be able to group validators together.

Does this answer your question? Also don't forget to please star and share.