---
title: Use Gin Binding for Validation
impact: HIGH
impactDescription: simplifies input handling and ensures consistent validation
tags: gin, go, validation, quality
---

## Use Gin Binding for Validation

Leverage Gin's built-in binding mechanism (`ShouldBindJSON`, `ShouldBindQuery`, etc.) and the `validator` library tags. This centralizes validation logic and keeps handlers clean.

**Incorrect (manual parsing and validation):**

```go
func CreateUser(c *gin.Context) {
    var raw map[string]interface{}
    if err := c.BindJSON(&raw); err != nil {
        c.JSON(400, gin.H{"error": "invalid json"})
        return
    }
    
    email, ok := raw["email"].(string)
    if !ok || email == "" {
        c.JSON(400, gin.H{"error": "email is required"})
        return
    }
    // ... more manual checks
}
```

**Correct (struct binding and tags):**

```go
type CreateUserRequest struct {
    Email    string `json:"email" binding:"required,email"`
    Password string `json:"password" binding:"required,min=8"`
    Age      int    `json:"age" binding:"gte=18"`
}

func CreateUser(c *gin.Context) {
    var req CreateUserRequest
    if err := c.ShouldBindJSON(&req); err != nil {
        c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
        return
    }
    
    // Process validated request
}
```

**Benefits:**
- Reduces boilerplate code in handlers
- Declarative validation is easier to read and maintain
- Automatically handles type conversion (e.g., string to int)
- Provides standard error messages

**Tools:** Gin, go-playground/validator
