Skip to main content

Request Validation

Developer Beginner

Validate user input to ensure data integrity and security.

Using Binding Tags

type CreateUserRequest struct {
Username string `json:"username" binding:"required,min=3,max=32,alphanum"`
Email string `json:"email" binding:"required,email"`
Password string `json:"password" binding:"required,min=8,max=128"`
Age int `json:"age" binding:"omitempty,min=18,max=120"`
}

func (c *UserController) CreateUser(ctx *gin.Context) {
var req CreateUserRequest

if err := ctx.ShouldBindJSON(&req); err != nil {
util.RespondWithError(ctx, util.NewErrorMessage("E4001", "Invalid request", err))
return
}

// Continue...
}

Common Validation Tags

  • required - Field must be present
  • omitempty - Skip validation if empty
  • min=N - Minimum value/length
  • max=N - Maximum value/length
  • email - Valid email format
  • url - Valid URL
  • alphanum - Alphanumeric only
  • numeric - Numeric only
  • oneof=red green blue - Must be one of specified values

Custom Validation

func (c *ProductController) CreateProduct(ctx *gin.Context) {
var req CreateProductRequest

if err := ctx.ShouldBindJSON(&req); err != nil {
util.RespondWithError(ctx, util.NewErrorMessage("E4001", "Invalid request", err))
return
}

// Custom business validation
if req.Price <= 0 {
util.RespondWithError(ctx, util.NewErrorMessage("E4001", "Price must be positive"))
return
}

if req.Stock < 0 {
util.RespondWithError(ctx, util.NewErrorMessage("E4001", "Stock cannot be negative"))
return
}

// Continue...
}

UUID Validation

func (c *UserController) GetUser(ctx *gin.Context) {
id := ctx.Param("id")

// Validate UUID format
if _, err := uuid.Parse(id); err != nil {
util.RespondWithError(ctx, util.NewErrorMessage("E4001", "Invalid user ID format"))
return
}

// Continue...
}

Best Practices

  • Validate at controller layer
  • Use binding tags when possible
  • Add custom validation for business rules
  • Return clear error messages
  • Never trust client input