validation

package
v1.8.0 Latest Latest
Warning

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

Go to latest
Published: Jan 15, 2026 License: Apache-2.0 Imports: 6 Imported by: 0

README

How validation works

This guide covers how to declare and use validations in your models.

Declaring Models

Models are defined using normal structs with validation tags. These structs can contain fields of any type, provided the associated constraint supports that type.

type System struct {
    ID     string  `validationID: "System.ID"`
    Region string  `validationID: "System.Region"`
    Type   string  `validationID: "System.Type"`
    Labels Map     `validationID: "System.Labels"`
}

Map types must implement the validation.Map interface to allow validation of its key-value pairs.

Configuring Validations

Validations are configured as a list of validation IDs with associated constraints.

validations:
    - id: System.Type
        constraints:
        - type: non-empty
    - id: System.Region
        constraints:
        - type: list
          spec:
            allowlist: ["region-application", "region-system"]
    - id: System.Labels.Team
        skipIfNotExists: true
        constraints:
        - type: non-empty

If a validation ID does not exist in any model, an error will be returned at initialization. Since validations can be defined for dynamic fields in map types, the skipIfNotExists flag can be set to true to skip the check at startup.

There are a couple of built-in constraints available:

Constraint Field Type Description Spec
list string Field must only contain allowlisted values allowlist: list of allowed values
non-empty string Field must not be empty (none)
non-empty-keys validation.Map implementer Field must not have empty keys (none)

Declaring Validations

Default validations can also be declared programmatically if a model returns a list of validation.Field.

func (s *System) ValidationFields() []validation.Field {
    return []validation.Field{
        {
            ID: "System.ID",
            Validators: []validation.Validator{
                validation.NonEmptyConstraint{},
            },
        },
    }
}

Initializing Validations

Validations must be initialized using validation.New which expects a validation.Config. validation.Config requires a list of config fields (see Configuring Validations) and models to validate.

config := validation.Config{
    Fields: fields,
    Models: []validation.Model{
        &System{},
    },
}
v, err := validation.New(config)

Using Validations

Once initialized, validations can be used to validate models but also individual fields.

To validate a model, first its values must be extracted by their validation IDs.

values, err := validation.GetValues(system)
if err != nil {
    // handle error
}
err = v.ValidateAll(values)

To validate an individual field, use its validation ID.

err = v.Validate("System.Type", system.Type)

Documentation

Index

Constants

View Source
const (
	ConstraintTypeList         = "list"
	ConstraintTypeNonEmpty     = "non-empty"
	ConstraintTypeNonEmptyKeys = "non-empty-keys"
	ConstraintTypeNonEmptyVals = "non-empty-vals"
	ConstraintTypeRegex        = "regex"
	ConstraintTypeMapKeys      = "map-keys"
)
View Source
const TagName = "validationID"

TagName is the struct tag name used for validation IDs.

Variables

View Source
var (
	ErrConstraintsMissing         = errors.New("no constraints provided")
	ErrEmptyConstraintType        = errors.New("constraint type is empty")
	ErrUnknownConstraintType      = errors.New("unknown constraint type")
	ErrConstraintSpecMissing      = errors.New("constraint spec is missing")
	ErrConstraintAllowListMissing = errors.New("constraint allow list is missing")
	ErrConstraintPatternMissing   = errors.New("constraint pattern is missing")
	ErrConstraintKeysMissing      = errors.New("constraint keys are missing")
	ErrConstraintKeyNameMissing   = errors.New("constraint key name is missing")
)
View Source
var (
	ErrEmptyID           = errors.New("id is empty")
	ErrValidatorsMissing = errors.New("no validators provided")
	ErrIDMustExist       = errors.New("id must exist")
)
View Source
var (
	ErrWrongType       = errors.New("value has wrong type")
	ErrValueNotAllowed = errors.New("value is not allowed")
	ErrValueEmpty      = errors.New("value is empty")
	ErrKeyEmpty        = errors.New("key is empty")
	ErrKeyMissing      = errors.New("required key is missing")
)

Functions

func GetValues

func GetValues(model Model) (map[ID]any, error)

GetValues gets all values from the given model mapped by their validation IDs.

Types

type Config

type Config struct {
	// Fields represents configuration fields.
	Fields []ConfigField
	// Models represents models to extract validations from and check for ID existence.
	Models []Model
}

Config represents the validation configuration.

type ConfigField

type ConfigField struct {
	ID              ID           `yaml:"id"`
	SkipIfNotExists bool         `yaml:"skipIfNotExists,omitempty"`
	Constraints     []Constraint `yaml:"constraints"`
}

ConfigField represents a configuration field with its validation constraints. If the ID is not defined via `TagName`, SkipIfNotExists needs to be set to true.

type Constraint

type Constraint struct {
	Type string          `yaml:"type"`
	Spec *ConstraintSpec `yaml:"spec,omitempty"`
}

Constraint represents a validation constraint for a configuration field.

type ConstraintSpec

type ConstraintSpec struct {
	AllowList []string     `yaml:"allowList,omitempty"`
	Pattern   string       `yaml:"pattern,omitempty"`
	Keys      []MapKeySpec `yaml:"keys,omitempty"`
}

ConstraintSpec holds the specification for a constraint.

type Field

type Field struct {
	ID         ID
	Validators []Validator
}

Field represents a model field with its validation ID and associated validators.

type ID

type ID string

ID represents a validation identifier.

type ListConstraint

type ListConstraint struct {
	AllowList []string `yaml:"allowList"`
}

ListConstraint validates that a value is within an allowed list.

func (ListConstraint) Validate

func (l ListConstraint) Validate(value any) error

Validate checks if the provided value is in the AllowList.

type MapKeyConstraintSpec added in v1.8.0

type MapKeyConstraintSpec struct {
	Name       string
	Required   bool
	Validators []Validator
}

MapKeyConstraintSpec holds the specification for validating a single map key.

type MapKeySpec added in v1.8.0

type MapKeySpec struct {
	Name        string       `yaml:"name"`
	Required    bool         `yaml:"required,omitempty"`
	Constraints []Constraint `yaml:"constraints,omitempty"`
}

MapKeySpec holds the specification for a map key constraint.

type MapKeysConstraint added in v1.8.0

type MapKeysConstraint struct {
	Keys []MapKeyConstraintSpec
}

MapKeysConstraint validates map keys according to the provided specifications.

func NewMapKeysConstraint added in v1.8.0

func NewMapKeysConstraint(keys []MapKeySpec) (*MapKeysConstraint, error)

NewMapKeysConstraint creates a new MapKeysConstraint from the provided key specifications.

func (*MapKeysConstraint) Validate added in v1.8.0

func (m *MapKeysConstraint) Validate(value any) error

Validate checks if the provided map value satisfies all key constraints.

type Model

type Model interface {
	Validations() []Field
}

Model defines an interface for models that provide their validation fields.

type NonEmptyConstraint

type NonEmptyConstraint struct{}

NonEmptyConstraint validates that a string value is not empty.

func (NonEmptyConstraint) Validate

func (n NonEmptyConstraint) Validate(value any) error

Validate checks if the provided value is a non-empty string.

type NonEmptyKeysConstraint

type NonEmptyKeysConstraint struct{}

NonEmptyKeysConstraint validates that all keys in a map are non-empty strings.

func (NonEmptyKeysConstraint) Validate

func (n NonEmptyKeysConstraint) Validate(value any) error

Validate checks if the provided value is a map where each key is non-empty.

type NonEmptyValConstraint added in v1.8.0

type NonEmptyValConstraint struct{}

NonEmptyValConstraint validates that all keys in a map have non-empty values.

func (NonEmptyValConstraint) Validate added in v1.8.0

func (n NonEmptyValConstraint) Validate(value any) error

Validate checks if the provided value is a map where each value corresponding to a key is non-empty.

type RegexConstraint added in v1.6.0

type RegexConstraint struct {
	// contains filtered or unexported fields
}

RegexConstraint validates that the string matches the configured regex patern.

func NewRegexConstraint added in v1.6.0

func NewRegexConstraint(pattern string) (*RegexConstraint, error)

NewRegexConstraint takes a pattern and returns a RegexConstraint with the compiled regex patern.

func (*RegexConstraint) Validate added in v1.6.0

func (r *RegexConstraint) Validate(value any) error

Validate checks if the provided value satisfies the regex constraint.

type Spec

type Spec struct {
	// contains filtered or unexported fields
}

Spec represents the validation specification for a given ID.

type Validation

type Validation struct {
	// contains filtered or unexported fields
}

Validation represents a map of validation specifications by their IDs.

func New

func New(cfg Config) (*Validation, error)

New creates a new Validation instance with the provided configuration fields.

func (*Validation) Validate

func (v *Validation) Validate(id ID, value any) error

Validate validates a single value by its ID.

func (*Validation) ValidateAll

func (v *Validation) ValidateAll(valuesByID map[ID]any) error

ValidateAll validates all provided values mapped by their IDs.

type Validator

type Validator interface {
	Validate(value any) error
}

Validator defines the interface for constraints.

Jump to

Keyboard shortcuts

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