Skip to Content

Validators

The validators package provides input validation with a rich set of built-in rules, support for custom validators, and structured error messages that integrate with the errors package.

Import

import "github.com/gofastadev/gofasta/pkg/validators"

Key Types

Validator

type Validator struct { errors []FieldError }

FieldError

type FieldError struct { Field string `json:"field"` Rule string `json:"rule"` Message string `json:"message"` }

ValidationResult

type ValidationResult struct { Valid bool `json:"valid"` Errors []FieldError `json:"errors,omitempty"` }

Rule

type Rule func(field string, value interface{}) *FieldError

Key Functions

FunctionSignatureDescription
Newfunc New() *ValidatorCreates a new validator instance
Validatefunc (v *Validator) Validate(field string, value interface{}, rules ...Rule) *ValidatorValidates a field against one or more rules
Resultfunc (v *Validator) Result() ValidationResultReturns the validation result
HasErrorsfunc (v *Validator) HasErrors() boolReturns true if any validation errors exist
ToAppErrorfunc (v *Validator) ToAppError() *errors.AppErrorConverts validation errors to an AppError

Built-in Rules

RuleDescription
Required()Field must not be zero value
MinLength(n int)String must be at least n characters
MaxLength(n int)String must be at most n characters
Email()Must be a valid email address
URL()Must be a valid URL
Min(n float64)Numeric value must be at least n
Max(n float64)Numeric value must be at most n
Between(min, max float64)Numeric value must be within range
In(values ...string)Must be one of the specified values
UUID()Must be a valid UUID
Regex(pattern string)Must match the regular expression
Date(layout string)Must be a valid date in the given format
Alpha()Must contain only letters
AlphaNumeric()Must contain only letters and numbers
Unique(field string, db *gorm.DB, table string)Must be unique in the database table

Usage

Basic Validation

v := validators.New() v.Validate("name", input.Name, validators.Required(), validators.MinLength(2), validators.MaxLength(100)) v.Validate("email", input.Email, validators.Required(), validators.Email()) v.Validate("age", input.Age, validators.Min(18), validators.Max(120)) v.Validate("role", input.Role, validators.Required(), validators.In("admin", "editor", "viewer")) if v.HasErrors() { result := v.Result() // result.Errors contains all field-level errors return v.ToAppError() }

Validation in a Controller

func (c *UserController) Create(w http.ResponseWriter, r *http.Request) { var input CreateUserInput if err := httputil.Bind(r, &input); err != nil { httputil.Error(w, errors.BadRequest(err.Error())) return } v := validators.New() v.Validate("name", input.Name, validators.Required(), validators.MinLength(2)) v.Validate("email", input.Email, validators.Required(), validators.Email()) v.Validate("password", input.Password, validators.Required(), validators.MinLength(8)) if v.HasErrors() { httputil.Error(w, v.ToAppError()) return } user, err := c.service.Create(r.Context(), input) if err != nil { httputil.Error(w, err) return } httputil.Created(w, "user created", user) }

The error response looks like:

{ "error": { "code": "VALIDATION_ERROR", "message": "validation failed", "detail": "[{\"field\":\"email\",\"rule\":\"email\",\"message\":\"must be a valid email address\"}]" } }

Custom Validators

Create custom rules by implementing the Rule function signature.

func PasswordStrength() validators.Rule { return func(field string, value interface{}) *validators.FieldError { password, ok := value.(string) if !ok { return &validators.FieldError{Field: field, Rule: "password_strength", Message: "must be a string"} } hasUpper := regexp.MustCompile(`[A-Z]`).MatchString(password) hasLower := regexp.MustCompile(`[a-z]`).MatchString(password) hasDigit := regexp.MustCompile(`[0-9]`).MatchString(password) if !hasUpper || !hasLower || !hasDigit { return &validators.FieldError{ Field: field, Rule: "password_strength", Message: "must contain uppercase, lowercase, and digit characters", } } return nil } } // Usage v.Validate("password", input.Password, validators.Required(), validators.MinLength(8), PasswordStrength())

Database Uniqueness Check

v.Validate("email", input.Email, validators.Required(), validators.Email(), validators.Unique("email", db, "users"), )
  • Errors — Validation errors map to VALIDATION_ERROR code
  • HTTP Utilities — Bind and validate request input
  • Types — Shared input types used with validators
Last updated on