Request Validation
3 minute read
The Rivaas Validation package provides flexible, multi-strategy validation for Go structs. Supports struct tags, JSON Schema, and custom interfaces. Includes detailed error messages and built-in security features.
Features
- Multiple Validation Strategies
- Struct tags via go-playground/validator
- JSON Schema (RFC-compliant)
- Custom interfaces (
Validate()/ValidateContext())
- Partial Validation - For PATCH requests where only provided fields should be validated
- Thread-Safe - Safe for concurrent use by multiple goroutines
- Security - Built-in protections against deep nesting, memory exhaustion, and sensitive data exposure
- Standalone - Can be used independently without the full Rivaas framework
- Custom Validators - Easy registration of custom validation tags
Quick Start
Basic Validation
The simplest way to use this package is with the package-level Validate function:
import "rivaas.dev/validation"
type User struct {
Email string `json:"email" validate:"required,email"`
Age int `json:"age" validate:"min=18"`
}
user := User{Email: "invalid", Age: 15}
if err := validation.Validate(ctx, &user); err != nil {
var verr *validation.Error
if errors.As(err, &verr) {
for _, fieldErr := range verr.Fields {
fmt.Printf("%s: %s\n", fieldErr.Path, fieldErr.Message)
}
}
}
Custom Validator Instance
For more control, create a Validator instance with custom options:
validator := validation.MustNew(
validation.WithRedactor(sensitiveFieldRedactor),
validation.WithMaxErrors(10),
validation.WithCustomTag("phone", phoneValidator),
)
if err := validator.Validate(ctx, &user); err != nil {
// Handle validation errors
}
Partial Validation (PATCH Requests)
For PATCH requests where only provided fields should be validated:
// Compute which fields are present in the JSON
presence, _ := validation.ComputePresence(rawJSON)
// Validate only the present fields
err := validator.ValidatePartial(ctx, &user, presence)
Learning Path
Follow these guides to master validation with Rivaas:
- Installation - Get started with the validation package
- Basic Usage - Learn the fundamentals of validation
- Struct Tags - Use go-playground/validator struct tags
- JSON Schema - Validate with JSON Schema
- Custom Interfaces - Implement Validate() methods
- Partial Validation - Handle PATCH requests correctly
- Error Handling - Work with structured errors
- Custom Validators - Register custom tags and functions
- Security - Protect sensitive data and prevent attacks
- Examples - Real-world integration patterns
Validation Strategies
The package supports three validation strategies that can be used individually or combined:
1. Struct Tags (go-playground/validator)
Use struct tags with go-playground/validator syntax:
type User struct {
Email string `validate:"required,email"`
Age int `validate:"min=18,max=120"`
Name string `validate:"required,min=2,max=100"`
}
2. JSON Schema
Implement the JSONSchemaProvider interface:
type User struct {
Email string `json:"email"`
Age int `json:"age"`
}
func (u User) JSONSchema() (id, schema string) {
return "user-schema", `{
"type": "object",
"properties": {
"email": {"type": "string", "format": "email"},
"age": {"type": "integer", "minimum": 18}
},
"required": ["email"]
}`
}
3. Custom Validation Interface
Implement ValidatorInterface for simple validation:
type User struct {
Email string
}
func (u *User) Validate() error {
if !strings.Contains(u.Email, "@") {
return errors.New("email must contain @")
}
return nil
}
// validation.Validate will automatically call u.Validate()
err := validation.Validate(ctx, &user)
Or implement ValidatorWithContext for context-aware validation:
func (u *User) ValidateContext(ctx context.Context) error {
// Access request-scoped data from context
tenant := ctx.Value("tenant").(string)
// Apply tenant-specific validation rules
return nil
}
Strategy Priority
The package automatically selects the best strategy based on the type:
Priority Order:
- Interface methods (
Validate()/ValidateContext()) - Struct tags (
validate:"...") - JSON Schema (
JSONSchemaProvider)
You can explicitly choose a strategy:
err := validator.Validate(ctx, &user, validation.WithStrategy(validation.StrategyTags))
Or run all applicable strategies:
err := validator.Validate(ctx, &user, validation.WithRunAll(true))
Comparison with Other Libraries
| Feature | rivaas.dev/validation | go-playground/validator | JSON Schema validators |
|---|---|---|---|
| Struct tags | ✅ | ✅ | ❌ |
| JSON Schema | ✅ | ❌ | ✅ |
| Custom interfaces | ✅ | ❌ | ❌ |
| Partial validation | ✅ | ❌ | ❌ |
| Multi-strategy | ✅ | ❌ | ❌ |
| Context support | ✅ | ❌ | Varies |
| Built-in redaction | ✅ | ❌ | ❌ |
| Thread-safe | ✅ | ✅ | Varies |
Next Steps
- Start with Installation to set up the validation package
- Explore the API Reference for complete technical details
- Check out examples for real-world integration patterns
For integration with rivaas/app, the Context provides convenient methods that handle validation automatically.
Feedback
Was this page helpful?
Glad to hear it! Please tell us how we can improve.
Sorry to hear that. Please tell us how we can improve.