> ## Documentation Index
> Fetch the complete documentation index at: https://docs.go-mizu.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Validator

> Request validation middleware with declarative rules.

## Overview

The `validator` middleware provides declarative request validation with built-in rules for common validation needs. It validates query parameters, form fields, headers, and path parameters.

Use it when you need:

* Input validation
* Form validation
* API parameter validation
* Custom validation rules

## Installation

```go theme={null}
import "github.com/go-mizu/mizu/middlewares/validator"
```

## Quick Start

```go theme={null}
app := mizu.New()

app.Post("/users", createUser, validator.New(
    validator.Field("email", "required", "email"),
    validator.Field("name", "required", "min:2", "max:50"),
))
```

## Built-in Rules

| Rule       | Description              | Example                    |
| ---------- | ------------------------ | -------------------------- |
| `required` | Field must not be empty  | `"required"`               |
| `min:n`    | Minimum string length    | `"min:3"`                  |
| `max:n`    | Maximum string length    | `"max:100"`                |
| `email`    | Valid email format       | `"email"`                  |
| `numeric`  | Numeric value            | `"numeric"`                |
| `integer`  | Integer value            | `"integer"`                |
| `alpha`    | Letters only             | `"alpha"`                  |
| `alphanum` | Letters and numbers only | `"alphanum"`               |
| `in:a,b,c` | Must be one of values    | `"in:pending,active,done"` |
| `url`      | Valid URL                | `"url"`                    |
| `uuid`     | Valid UUID format        | `"uuid"`                   |

## Examples

### Basic Validation

```go theme={null}
app.Post("/register", registerHandler, validator.New(
    validator.Field("username", "required", "alphanum", "min:3", "max:20"),
    validator.Field("email", "required", "email"),
    validator.Field("password", "required", "min:8"),
))
```

### Optional Fields

```go theme={null}
app.Put("/profile", updateProfile, validator.New(
    validator.OptionalField("bio", "max:500"),
    validator.OptionalField("website", "url"),
))
```

### Enum Validation

```go theme={null}
app.Post("/tasks", createTask, validator.New(
    validator.Field("title", "required", "min:1", "max:200"),
    validator.Field("status", "required", "in:pending,in_progress,done"),
    validator.Field("priority", "required", "in:low,medium,high"),
))
```

### JSON Body Validation

```go theme={null}
app.Post("/api/users", createUser, validator.JSON(map[string][]string{
    "email":    {"required", "email"},
    "name":     {"required", "min:2"},
    "age":      {"numeric"},
}))
```

### Custom Error Handler

```go theme={null}
app.Use(validator.WithOptions(validator.Options{
    Rules: []validator.Rule{
        validator.Field("email", "required", "email"),
    },
    ErrorHandler: func(c *mizu.Ctx, errors validator.ValidationErrors) error {
        return c.JSON(422, map[string]any{
            "message": "Validation failed",
            "errors":  errors,
        })
    },
}))
```

### Custom Error Messages

```go theme={null}
app.Post("/contact", contactHandler, validator.New(
    validator.Rule{
        Field:   "email",
        Rules:   []string{"required", "email"},
        Message: "Please provide a valid email address",
    },
    validator.Rule{
        Field:   "message",
        Rules:   []string{"required", "min:10"},
        Message: "Message must be at least 10 characters",
    },
))
```

### Multiple Validation Groups

```go theme={null}
// Login validation
loginRules := validator.New(
    validator.Field("email", "required", "email"),
    validator.Field("password", "required"),
)

// Registration validation
registerRules := validator.New(
    validator.Field("email", "required", "email"),
    validator.Field("password", "required", "min:8"),
    validator.Field("name", "required", "min:2"),
)

app.Post("/login", loginHandler, loginRules)
app.Post("/register", registerHandler, registerRules)
```

### Query Parameter Validation

```go theme={null}
// GET /users?page=1&limit=20&status=active
app.Get("/users", listUsers, validator.New(
    validator.OptionalField("page", "integer"),
    validator.OptionalField("limit", "integer"),
    validator.OptionalField("status", "in:active,inactive,pending"),
))
```

## API Reference

### Functions

```go theme={null}
// New creates validator with rules
func New(rules ...Rule) mizu.Middleware

// WithOptions creates validator with full configuration
func WithOptions(opts Options) mizu.Middleware

// JSON validates JSON body against rules
func JSON(rules map[string][]string) mizu.Middleware

// Field creates a required field rule
func Field(name string, rules ...string) Rule

// OptionalField creates an optional field rule
func OptionalField(name string, rules ...string) Rule
```

### Types

```go theme={null}
type Rule struct {
    Field    string
    Rules    []string
    Message  string
    Optional bool
}

type ValidationError struct {
    Field   string `json:"field"`
    Message string `json:"message"`
}

type ValidationErrors []ValidationError
```

### Field Sources

The validator checks these sources in order:

1. Query parameters
2. Form values (POST/PUT)
3. Headers
4. Path parameters

## Error Response

Default error response format:

```json theme={null}
{
    "error": "validation failed",
    "errors": [
        {"field": "email", "message": "is required"},
        {"field": "name", "message": "must be at least 2 characters"}
    ]
}
```

## Technical Details

### Architecture

The validator middleware is built on a pipeline architecture that processes validation rules sequentially:

1. **Field Value Extraction**: The middleware retrieves field values from multiple sources in order of precedence:
   * Query parameters (highest priority)
   * Form values (POST/PUT requests)
   * Headers
   * Path parameters (lowest priority)

2. **Rule Application**: Each validation rule is parsed and applied to the field value:
   * Rule format: `ruleName` or `ruleName:parameter`
   * Rules are checked sequentially for each field
   * First validation failure stops checking additional rules for that field

3. **Error Handling**: Validation errors are collected and either:
   * Passed to a custom error handler (if provided)
   * Returned as JSON with 400 Bad Request (default)

### Implementation Details

**Validation Flow**:

```
Request → Extract Field Values → Apply Rules → Collect Errors → Error Handler or Next
```

**Rule Parsing**:

* Rules are split on `:` to separate the rule name from its parameter
* The `applyRule` function handles all built-in validation logic
* Unknown rules are silently ignored

**Optional Fields**:

* When a field is marked as optional and empty, all its rules are skipped
* Empty is defined as an empty string (`""`)
* If an optional field has a value, all rules are applied normally

**JSON Validation**:

* Reads the entire request body into memory
* Parses JSON into `map[string]any`
* Converts non-string values using `stringify` helper
* Supports string, float64, and bool type conversion

**Custom Messages**:

* The `Message` field in a `Rule` overrides default error messages
* Custom messages apply to all validation rules for that field
* If not set, each rule has its own default message

### Performance Characteristics

* **Memory**: Minimal allocation for most validations; JSON validation reads entire body
* **CPU**: Linear with number of fields and rules; regex-free for better performance
* **Concurrency**: Safe for concurrent use; no shared state between requests

## Best Practices

* Validate all user input
* Use appropriate rules for data types
* Provide clear error messages
* Validate early in the middleware chain
* Use optional fields for non-required parameters
* Combine multiple rules for comprehensive validation
* Consider custom error handlers for consistent API responses

## Testing

### Test Coverage

The validator middleware includes comprehensive test coverage for all validation rules and scenarios:

| Test Case                   | Description                                                       | Expected Behavior                                   |
| --------------------------- | ----------------------------------------------------------------- | --------------------------------------------------- |
| **Basic Validation**        |                                                                   |                                                     |
| Valid request               | Request with all required fields meeting validation rules         | Returns 200 OK                                      |
| Missing required field      | Request missing a field marked as required                        | Returns 400 Bad Request                             |
| Invalid email               | Email field with invalid format (missing @ or .)                  | Returns 400 Bad Request                             |
| Min length violation        | Field value shorter than minimum length requirement               | Returns 400 Bad Request                             |
| **Optional Fields**         |                                                                   |                                                     |
| Without optional field      | Request without an optional field present                         | Returns 200 OK                                      |
| With valid optional field   | Request with optional field that passes validation                | Returns 200 OK                                      |
| With invalid optional field | Request with optional field failing validation                    | Returns 400 Bad Request                             |
| **Validation Rules**        |                                                                   |                                                     |
| Required pass               | Non-empty value for required field                                | Validation passes                                   |
| Required fail               | Empty value for required field                                    | Validation fails                                    |
| Min pass                    | Value length >= minimum                                           | Validation passes                                   |
| Min fail                    | Value length \< minimum                                           | Validation fails                                    |
| Max pass                    | Value length {'<='} maximum                                       | Validation passes                                   |
| Max fail                    | Value length > maximum                                            | Validation fails                                    |
| Email pass                  | Valid email format with @ and .                                   | Validation passes                                   |
| Email fail                  | Invalid email format                                              | Validation fails                                    |
| Numeric pass                | Valid numeric value (e.g., "123.45")                              | Validation passes                                   |
| Numeric fail                | Non-numeric value                                                 | Validation fails                                    |
| Integer pass                | Valid integer value (e.g., "123")                                 | Validation passes                                   |
| Integer fail                | Non-integer value (e.g., "12.3")                                  | Validation fails                                    |
| Alpha pass                  | Letters only value                                                | Validation passes                                   |
| Alpha fail                  | Value with non-letter characters                                  | Validation fails                                    |
| Alphanum pass               | Letters and numbers only                                          | Validation passes                                   |
| Alphanum fail               | Value with special characters                                     | Validation fails                                    |
| In pass                     | Value matching one of allowed options                             | Validation passes                                   |
| In fail                     | Value not in allowed options list                                 | Validation fails                                    |
| URL pass                    | Valid URL with http\:// or https\://                              | Validation passes                                   |
| URL fail                    | Invalid URL format                                                | Validation fails                                    |
| UUID pass                   | Valid UUID format (36 chars with hyphens at positions 8,13,18,23) | Validation passes                                   |
| UUID fail                   | Invalid UUID format                                               | Validation fails                                    |
| **Custom Error Handler**    |                                                                   |                                                     |
| Custom error handler        | Validation failure with custom error handler                      | Returns custom status code (422) with custom format |
| **JSON Validation**         |                                                                   |                                                     |
| Valid JSON                  | JSON body with valid fields                                       | Returns 200 OK                                      |
| Invalid JSON values         | JSON body with fields failing validation                          | Returns 400 Bad Request                             |
| Malformed JSON              | Unparseable JSON body                                             | Returns 400 Bad Request                             |
| **Error Formatting**        |                                                                   |                                                     |
| Multiple validation errors  | Multiple fields failing validation                                | Returns formatted error string with all failures    |
| Empty validation errors     | No validation errors                                              | Returns "validation failed" message                 |
| **Field Helper Functions**  |                                                                   |                                                     |
| Field creation              | Creating required field rule                                      | Returns Rule with correct field name and rules      |
| OptionalField creation      | Creating optional field rule                                      | Returns Rule with Optional=true                     |

## Related Middlewares

* [contenttype](/middlewares/contenttype) - Content-Type validation
* [bodylimit](/middlewares/bodylimit) - Body size limits
