Skip to content

Request Validation

Learn how to validate requests in Iris.

Basic Validation

go
package main

import (
    "github.com/kataras/iris/v12"
    "github.com/go-playground/validator/v10"
)

type User struct {
    Name     string `json:"name" validate:"required,min=2"`
    Email    string `json:"email" validate:"required,email"`
    Age      int    `json:"age" validate:"required,gte=0,lte=130"`
    Password string `json:"password" validate:"required,min=8"`
}

func main() {
    app := iris.New()
    validate := validator.New()

    app.Post("/users", func(ctx iris.Context) {
        var user User
        if err := ctx.ReadJSON(&user); err != nil {
            ctx.StopWithError(iris.StatusBadRequest, err)
            return
        }

        if err := validate.Struct(user); err != nil {
            if validationErrors, ok := err.(validator.ValidationErrors); ok {
                errors := make([]string, len(validationErrors))
                for i, e := range validationErrors {
                    errors[i] = e.Field() + " failed " + e.Tag() + " validation"
                }

                ctx.StopWithProblem(iris.StatusBadRequest, iris.NewProblem().
                    Title("Validation Error").
                    Detail("One or more fields failed validation").
                    Key("errors", errors))
                return
            }
        }

        ctx.JSON(iris.Map{
            "message": "User validated successfully",
            "user": user,
        })
    })

    app.Listen(":8080")
}

Custom Validation

go
type Registration struct {
    Username        string `json:"username" validate:"required,min=3"`
    Email           string `json:"email" validate:"required,email"`
    Password        string `json:"password" validate:"required,min=8"`
    ConfirmPassword string `json:"confirm_password" validate:"required,eqfield=Password"`
}

func passwordsMatch(fl validator.FieldLevel) bool {
    return fl.Field().String() == fl.Parent().FieldByName("Password").String()
}

func main() {
    app := iris.New()
    validate := validator.New()

    // Register custom validation
    validate.RegisterValidation("passwords_match", passwordsMatch)

    app.Post("/register", func(ctx iris.Context) {
        var reg Registration
        if err := ctx.ReadJSON(&reg); err != nil {
            ctx.StopWithError(iris.StatusBadRequest, err)
            return
        }

        if err := validate.Struct(reg); err != nil {
            ctx.StopWithProblem(iris.StatusBadRequest, iris.NewProblem().
                Title("Validation Error").
                DetailErr(err))
            return
        }

        ctx.JSON(iris.Map{
            "message": "Registration successful",
        })
    })

    app.Listen(":8080")
}

Cross-Field Validation

go
type DateRange struct {
    Start time.Time `json:"start" validate:"required"`
    End   time.Time `json:"end" validate:"required,gtfield=Start"`
}

app.Post("/daterange", func(ctx iris.Context) {
    var dates DateRange
    if err := ctx.ReadJSON(&dates); err != nil {
        ctx.StopWithError(iris.StatusBadRequest, err)
        return
    }

    if err := validate.Struct(dates); err != nil {
        ctx.StopWithProblem(iris.StatusBadRequest, iris.NewProblem().
            Title("Validation Error").
            DetailErr(err))
        return
    }

    ctx.JSON(iris.Map{
        "message": "Date range is valid",
        "dates": dates,
    })
})

Best Practices

  1. Validation Rules:

    • Use descriptive tags
    • Implement custom rules
    • Handle cross-field validation
    • Document requirements
    • Test edge cases
  2. Error Handling:

    • Provide clear messages
    • Return proper status codes
    • Log validation errors
    • Handle all cases
    • Document errors
  3. Security:

    • Validate all input
    • Set proper limits
    • Handle special characters
    • Monitor validation
    • Prevent injection
  4. Performance:

    • Cache validator
    • Optimize rules
    • Handle timeouts
    • Monitor performance
    • Clean resources

Built with excellence by Hellenic Development, delivering enterprise-grade solutions.