Validation Rules
Learn how validation rules work in NLG Form using reusable, composable, type-safe rule pipelines for strings, numbers, booleans, slices, formats, and cross-field validation.
Validation rules are the core building blocks of form.
They define how application data is validated through reusable, composable, and type-safe validation pipelines.
Unlike tag-based validators that hide validation behavior inside struct metadata, form treats validation as explicit application logic.
Validation Philosophy
Rules in form are:
- explicit
- reusable
- composable
- transport-independent
- type-safe
- generics-based
Validation is performed through reusable field references and rule pipelines instead of reflection-heavy struct tags.
Example:
return form.Schema[RegisterRequest]{
rules.Required(RegisterForm.Email),
rules.Email(RegisterForm.Email),
rules.MinLen(RegisterForm.Password, 8),
}This keeps validation logic:
- readable
- testable
- reusable
- maintainable in larger applications
Validation Flow
Validation typically follows three steps:
- Define typed fields
- Attach validation rules
- Combine rules into a reusable schema
Typed Fields
Validation starts by defining reusable typed fields.
RegisterForm := struct {
Email form.StringField[RegisterRequest]
Password form.StringField[RegisterRequest]
}{
Email: form.Str[RegisterRequest]("email", func(r *RegisterRequest) string {
return r.Email
}),
Password: form.Str[RegisterRequest]("password", func(r *RegisterRequest) string {
return r.Password
}),
}Field definitions contain:
- field names
- typed accessors
- reusable validation references
- transport-independent field metadata
Rule Composition
Rules are attached directly to typed field references.
return form.Schema[RegisterRequest]{
rules.Required(RegisterForm.Email),
rules.Email(RegisterForm.Email),
rules.MinLen(RegisterForm.Password, 8),
}Schemas can later be reused across:
- HTTP APIs
- background jobs
- CLI tools
- internal services
- shared validation packages
Rule Categories
The validation system is split into multiple rule categories.
Boolean Rules
Boolean rules validate bool values.
Typical use cases:
- terms acceptance
- feature flags
- consent validation
- visibility switches
Examples:
rules.IsTrue(SettingsForm.TermsAccepted)
rules.IsFalse(SettingsForm.Admin)Float Rules
Float rules validate decimal numeric values.
Typical use cases:
- pricing
- percentages
- measurements
- coordinates
Examples:
rules.MinFloat64(ProductForm.Price, 0)
rules.BetweenFloat64(ProductForm.Discount, 0, 100)Integer Rules
Integer rules validate integer values.
Typical use cases:
- quantities
- priorities
- age validation
- pagination
Examples:
rules.Min(UserForm.Age, 18)
rules.Positive(OrderForm.Quantity)String Rules
String rules validate textual values.
Typical use cases:
- usernames
- passwords
- slugs
- labels
Examples:
rules.Required(UserForm.Username)
rules.MinLen(UserForm.Password, 8)
rules.HasPrefix(PostForm.Slug, "app-")Time Rules
Time rules validate time.Time values.
Typical use cases:
- scheduling
- bookings
- expiration dates
- event windows
Examples:
rules.After(EventForm.StartAt, time.Now())
rules.Before(EventForm.EndAt, maxDate)Required Rules
Required rules change validation behavior for empty values.
Without required validation, empty values are generally skipped.
Examples:
rules.Required(UserForm.Email)
rules.RequiredInt(OrderForm.Quantity)
rules.RequiredTime(EventForm.StartAt)Slice Rules
Slice rules validate arrays and collections.
Typical use cases:
- tags
- permissions
- category selection
- batch operations
Examples:
rules.RequiredSlice(PostForm.Tags)
rules.UniqueItems(PostForm.Tags)Format Rules
Format rules validate structured string formats.
Typical use cases:
- URLs
- UUIDs
- IP addresses
- JSON strings
- timezones
Examples:
rules.URL(Form.Website)
rules.UUID(Form.UserID)
rules.IP(Form.ClientIP)Generic Rules
Generic rules validate reusable comparable values.
Typical use cases:
- enums
- statuses
- plans
- workflow states
Examples:
rules.OneOf(Form.Status.Field, "draft", "published")Compare Rules
Compare rules validate relationships between multiple fields.
Typical use cases:
- password confirmation
- numeric ranges
- ordered values
- matching identifiers
Examples:
rules.Compare(
Form.Password.Field,
Form.ConfirmPassword.Field,
rules.OpEQ,
)Design Goals
The validation system is designed around several core principles:
- explicit validation behavior
- reusable schemas
- composable rule pipelines
- transport-independent validation
- type-safe field access
- predictable validation flow
- low reflection overhead
Notes
- Validation rules are fully reusable across applications and transport layers.
- Empty values are generally skipped unless explicitly required.
- Rules are composable and can be grouped into reusable schema fragments.
- Validation logic remains independent from JSON, HTTP, CLI, or database layers.
- The package favors explicit validation pipelines over reflection-heavy struct tags.
- Rules are designed for modern Go applications using generics and reusable application architecture.
Response Customization
Learn how to customize validation responses in NLG Form using custom messages, unique error codes, and configurable HTTP validation response options.
Boolean Rules
Learn how to validate boolean fields in NLG Form using true, false, equality, and custom error code validation rules.