validate

package module
v0.24.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 9, 2026 License: Apache-2.0 Imports: 19 Imported by: 0

README

Package validate

Type-safe data validation in Go, Zod/Joi style (code-based schemas), with defaults, opt-in coercion, errors with paths, and support for validating structs and JSON ([]byte / json.RawMessage).

Why validate?

1. AST-Based Validation (Missing vs Null)

Most Go validators conflate zero values (0, "") with missing values. validate builds an Abstract Syntax Tree (AST) of your input first.

  • Missing: The field was not present in the input (e.g. JSON key missing).
  • Null: The field was present but explicit null.
  • Value: The field has a value (even if it's 0 or empty string).

This allows you to implement efficient PATCH APIs where "missing" means "don't touch" and "null" means "unset".

2. DDD Friendly (Schema Decoupled from Structs)

Your domain models (structs) remain pure. No validate:"required" tags polluting your entities. Validation logic lives in the Infrastructure or Presentation layer, defined explicitly in Go code.

3. Type Safety (Generics + Reflection)

validate uses Go generics (v.Object[User]) to ensure your schema matches your struct. If you rename a field in the struct but forget the schema, validation might fail or panic fast (depending on configuration), but type reference is safe. Methods like .Field(&u.Name) use pointer analysis to link schema rules to struct fields safely.

Installation

go get github.com/leandroluk/gox/validate

Summary

Quick Start

Basic Primitives
package main

import (
    "fmt"
    v "github.com/leandroluk/gox/validate"
)

func main() {
    nameSchema := v.Text().Required().Min(3).Max(50)
    value, err := nameSchema.Validate("John Doe")
    if err != nil {
        fmt.Println(err)
        return
    }
    fmt.Println(value) // "John Doe"
}
Struct Validation (Fluent API)
type User struct {
    Name    string
    Age     int
    Tags    []string
    Address Address
}

type Address struct {
    City string
}

func main() {
    // Define schema
    schema := v.Object(func(u *User, s *v.ObjectSchema[User]) {
        s.Field(&u.Name).Text().Required().Min(3)
        s.Field(&u.Age).Number().Integer().Min(0).Max(130)
        
        // Nested Array
        s.Field(&u.Tags).Array(v.Text().Min(2)).Max(10)

        // Nested Object
        s.Field(&u.Address).Object(func(a *Address, s *v.ObjectSchema[Address]) {
            s.Field(&a.City).Text().Required()
        })
    })

    // Validate
    jsonInput := []byte(`{
        "name": "Jane", 
        "age": 25, 
        "tags": ["dev", "go"], 
        "address": {"city": "New York"}
    }`)
    
    user, err := schema.Validate[User](jsonInput)
    if err != nil {
        // err is v.ValidationError
        fmt.Println(err)
    }
    fmt.Printf("%+v\n", user)
}

Features

Defaults & null

By default, standard values apply to both missing and null. To disable defaults for null (allow null to pass as zero value or error): v.WithDefaultOnNull(false).

Coercion (Opt-in)

validate does not coerce types blindly. You must opt-in.

v.Number[int]().Validate("123", v.WithCoerce(true)) // 123

Flags for specific behavior:

  • WithCoerceTrimSpace(true): " 123 " -> 123
  • WithCoerceNumberUnderscore(true): "1_000" -> 1000
Fluent Builders
  • Text: Required, Min/MaxLen, Pattern, Email, UUID...
  • Number: Min/Max, Integer, Positive...
  • Boolean: True, False...
  • Date: Min/Max, After/Before...
  • Array: Min/Max (items), Unique, Items(Schema)...
  • Object: Field, StructOnly, NoStructLevel...
  • Record: Min/Max (keys), Key(Schema), Value(Schema)...
Transformation

Use .Transform to parse or convert values safely during the validation pass.

s.Field(&t.Algorithm).Transform(func(val any) (any, error) {
    str, ok := val.(string)
    if !ok {
        return nil, errors.New("expected string")
    }
    // Mapping string to internal Enum/Type
    if method, ok := myMap[str]; ok {
        return method, nil
    }
    return nil, errors.New("unknown algorithm")
})
Internationalization (i18n) & Custom Messages

The library allows you to easily override standard validation messages globally by modifying the exported Msg variables in each schema package. This is perfectly suited for translations or custom error phrasing.

import "github.com/leandroluk/gox/validate/schema/number"

func init() {
    // Override standard messages globally for the number schema
    number.Msg.Eq = "deve ser igual a"
    number.Msg.Gt = "deve ser maior que"
    number.Msg.Min = "valor muito pequeno"
}

This strongly-typed pattern gives you IDE auto-completion and prevents typos compared to map-based dictionary configurations.

Error Handling

Errors are returned as v.ValidationError, which contains a list of issues. Each issue has:

  • Path: user.address.city or tags[0]
  • Message: "required", "too short"
  • Code: text.min, object.required

Documentation

Full documentation is available via GoDoc and strict typing in your IDE.

Documentation

Overview

Package validate provides a fluent, type-safe, and AST-based validation library for Go.

It separates schema definition from domain models, supports distinguishing between "null" and "missing" fields, and offers a rich set of composable validation rules.

Index

Constants

View Source
const CodeOneOf = combinator.CodeOneOf

Variables

This section is empty.

Functions

func AnyOf

func AnyOf[T any](schemaList ...combinator.Schema[T]) *combinator.AnyOfSchema[T]

AnyOf creates a combinator schema that succeeds if at least one of the provided schemas succeeds.

func Array

func Array[E any]() *array.Schema[E]

Array creates a new ArraySchema for elements of type E.

func Boolean

func Boolean() *boolean.Schema

Boolean creates a new BooleanSchema.

func Date

func Date() *date.Schema

Date creates a new DateSchema for time.Time validation.

func Duration

func Duration() *duration.Schema

Duration creates a new DurationSchema for time.Duration validation.

func Number

func Number[N types.Number]() *number.Schema[N]

Number creates a new NumberSchema[N] for numeric validation. N can be any integer or float type.

func Object

func Object[T any](builder func(target *T, schemaValue *object.Schema[T])) *object.Schema[T]

Object creates a new ObjectSchema for type T. The builder function is used to define fields and semantic rules on the schema.

func OneOf

func OneOf[T any](schemaList ...combinator.Schema[T]) *combinator.OneOfSchema[T]

OneOf creates a combinator schema that succeeds if exactly one of the provided schemas succeeds.

func Record

func Record[V any]() *record.Schema[V]

Record creates a new RecordSchema for maps with values of type V.

func Register

func Register(schemaValue AnySchema)

Register registers a schema in the global registry for its output type.

func ResetRegistry

func ResetRegistry()

ResetRegistry clears all registered schemas. Useful for testing.

func Text

func Text() *text.Schema

Text creates a new TextSchema for string validation.

func Validate

func Validate[T any](input any, optionList ...Option) (T, error)

Validate validates the input against the registered schema for type T. Returns the validated/coerced value of type T or an error.

Types

type AnyOfSchema

type AnyOfSchema[T any] = combinator.AnyOfSchema[T]

AnyOfSchema succeeds if at least one schema succeeds.

type AnySchema

type AnySchema = schema.AnySchema

AnySchema represents any type that can validate input.

type ArraySchema

type ArraySchema[E any] = array.Schema[E]

ArraySchema validates lists/slices.

type BooleanFieldBuilder

type BooleanFieldBuilder[T any] = object.BooleanFieldBuilder[T]

BooleanFieldBuilder is the entry point for defining rules on boolean fields.

type BooleanSchema

type BooleanSchema = boolean.Schema

BooleanSchema validates booleans.

type CombinatorSchema

type CombinatorSchema[T any] = combinator.Schema[T]

CombinatorSchema combines multiple schemas.

type ConditionOp

type ConditionOp = object.ConditionOp

ConditionOp is a type that represents a condition operator used in conditional validation.

type Context

type Context = engine.Context

Context holds the state of the current validation, including the path and issues found.

type DateFieldBuilder

type DateFieldBuilder[T any] = object.DateFieldBuilder[T]

DateFieldBuilder is the entry point for defining rules on date fields.

type DateSchema

type DateSchema = date.Schema

DateSchema validates time.Time values.

type DurationFieldBuilder

type DurationFieldBuilder[T any] = object.DurationFieldBuilder[T]

DurationFieldBuilder is the entry point for defining rules on duration fields.

type DurationSchema

type DurationSchema = duration.Schema

DurationSchema validates time.Duration values.

type FieldBuilder

type FieldBuilder[T any] = object.FieldBuilder[T]

FieldBuilder is the entry point for defining field rules.

type Formatter

type Formatter = schema.Formatter

Formatter formats validation error messages.

type Issue

type Issue = issues.Issue

Issue represents a single validation failure.

type NumberFieldBuilder

type NumberFieldBuilder[T any] = object.NumberFieldBuilder[T]

NumberFieldBuilder is the entry point for defining rules on numeric fields.

type NumberSchema

type NumberSchema[N types.Number] = number.Schema[N]

NumberSchema validates numeric values (int, float, etc).

type ObjectSchema

type ObjectSchema[T any] = object.Schema[T]

ObjectSchema validates structs or maps against defined fields.

type OneOfSchema

type OneOfSchema[T any] = combinator.OneOfSchema[T]

OneOfSchema succeeds if exactly one schema succeeds.

type Option

type Option = schema.Option

Option is a function that configures Options.

func WithAdditionalDateLayouts

func WithAdditionalDateLayouts(layouts ...string) Option

WithAdditionalDateLayouts adds more date parsing layouts to the defaults.

func WithCoerce

func WithCoerce(value bool) Option

WithCoerce enables automatic type coercion (e.g. string "123" to int 123).

func WithCoerceDateUnixMilliseconds

func WithCoerceDateUnixMilliseconds(value bool) Option

WithCoerceDateUnixMilliseconds allows coercing unix timestamp (ms) to Date.

func WithCoerceDateUnixSeconds

func WithCoerceDateUnixSeconds(value bool) Option

WithCoerceDateUnixSeconds allows coercing unix timestamp (seconds) to Date.

func WithCoerceDurationMilliseconds

func WithCoerceDurationMilliseconds(value bool) Option

WithCoerceDurationMilliseconds allows coercing numeric milliseconds to Duration.

func WithCoerceDurationSeconds

func WithCoerceDurationSeconds(value bool) Option

WithCoerceDurationSeconds allows coercing numeric seconds to Duration.

func WithCoerceNumberUnderscore

func WithCoerceNumberUnderscore(value bool) Option

WithCoerceNumberUnderscore allows underscores in number strings (e.g. "1_000").

func WithCoerceTrimSpace

func WithCoerceTrimSpace(value bool) Option

WithCoerceTrimSpace trims spaces from strings before validation/coercion.

func WithDateLayouts

func WithDateLayouts(layouts ...string) Option

WithDateLayouts overrides the default date parsing layouts.

func WithDefaultOnNull

func WithDefaultOnNull(value bool) Option

WithDefaultOnNull enables setting default values when input is explicit null.

func WithFailFast

func WithFailFast(value bool) Option

WithFailFast stops validation on the first error.

func WithFormatter

func WithFormatter(formatter Formatter) Option

WithFormatter sets a custom error message formatter.

func WithMaxIssues

func WithMaxIssues(value int) Option

WithMaxIssues limits the number of issues reported. Validation stops after reaching this limit.

func WithOmitZero

func WithOmitZero(value bool) Option

WithOmitZero treats zero values (e.g. 0, "") as missing/undefined.

func WithTimeLocation

func WithTimeLocation(value *time.Location) Option

WithTimeLocation sets the time location for date parsing/formatting.

type Options

type Options = schema.Options

Options configures the validator behavior.

type RecordSchema

type RecordSchema[V any] = record.Schema[V]

RecordSchema validates maps with homogeneous value types.

type Reporter added in v0.18.6

type Reporter = ruleset.Reporter

Reporter is the interface passed to Custom rules for reporting validation issues.

type Rule added in v0.18.5

type Rule[T any] = ruleset.Rule[T]

Rule is a named validation rule with a key and apply function.

type RuleFn added in v0.18.5

type RuleFn[T any] = ruleset.RuleFn[T]

RuleFn is the function signature for custom validation rules used in Custom().

type TextFieldBuilder

type TextFieldBuilder[T any] = object.TextFieldBuilder[T]

TextFieldBuilder is the entry point for defining rules on string fields.

type TextSchema

type TextSchema = text.Schema

TextSchema validates strings.

type ValidationError

type ValidationError = issues.ValidationError

ValidationError is an error type that aggregates multiple validation issues.

type Value

type Value = ast.Value

Value represents an abstract value in the validation AST.

Directories

Path Synopsis
internal
ast
internal/ast/ast.go
internal/ast/ast.go
codec
internal/codec/codec.go
internal/codec/codec.go
defaults
internal/defaults/defaults.go
internal/defaults/defaults.go
engine
internal/engine/engine.go
internal/engine/engine.go
issues
internal/issues/issues.go
internal/issues/issues.go
path
internal/path/path.go
internal/path/path.go
reflection
internal/reflection/reflection.go
internal/reflection/reflection.go
registry
internal/registry/registry.go
internal/registry/registry.go
ruleset
internal/ruleset/ruleset.go
internal/ruleset/ruleset.go
testkit
internal/testkit/testkit.go
internal/testkit/testkit.go
validate/schema/options.go
validate/schema/options.go
array
schema/array/array.go
schema/array/array.go
boolean
schema/boolean/boolean.go
schema/boolean/boolean.go
combinator
schema/combinator/combinator.go
schema/combinator/combinator.go
date
schema/date/date.go
schema/date/date.go
duration
schema/duration/duration.go
schema/duration/duration.go
number
schema/number/number.go
schema/number/number.go
number/util
schema/number/util/util.go
schema/number/util/util.go
object
schema/object/object.go
schema/object/object.go
record
schema/record/record.go
schema/record/record.go
text
schema/text/text.go
schema/text/text.go

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL