Layer validation: Combining generated validation with business logic
mainA best practice when using govalid is to layer your validation in three stages:
- Generated validation: Use
govalidmarkers for basic field constraints (type, length, format, presence). - Business logic: Implement manual checks for complex rules that involve relationships between multiple fields (e.g., "if Priority is High, then AssignedToRole cannot be Guest").
- Integration validation: Validate against external dependencies or state.
Example pattern:
func CreateTask(task *Task) error {
// 1. Run generated validation
if err := ValidateTask(task); err != nil {
return err
}
// 2. Run business logic validation
if task.Priority == PriorityHigh && task.AssignedToRole == RoleGuest {
return fmt.Errorf("high priority tasks cannot be assigned to guests")
}
return nil
}