verax

module
v0.13.0 Latest Latest
Warning

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

Go to latest
Published: Jun 7, 2026 License: MIT

README

verax

Truthful validation for Go — Collect all errors in one pass. Beautiful, JSON-serializable errors. Perfect for APIs. Powered by xrr.

Go Version License pkg.go.dev Changelog Go Report Card


Why verax?

Go validation libraries often force you to choose between:

  • Stopping at the first error (bad UX for users)
  • Returning ugly, hard-to-parse errors

verax solves both: it validates everything in a single pass, collects * all* failures, and returns clean, structured errors that are ready to serialize to JSON and send straight to your API clients.

Built on top of xrr — so you get stable error codes, rich metadata, and full compatibility with errors.Is/As, slog, and more.


Features
  • All-errors-in-one-passValidateStruct reports every field failure
  • Production-ready JSON — Errors implement json.Marshaler perfectly for API responses
  • Simple, fluent APIValidate, ValidateStruct, Field, and rich rules
  • Built-in rules galoreRequired, Min/Max, Length, Match, In, Each, Map, network rules, semver, and more
  • Struct tags — Uses json tag by default (customizable)
  • Self-validating structs — Implement verax.Validator
  • Complex data — First-class support for slices, arrays, and maps (with indexed/key errors)
  • Fully extensible — Custom rules via Rule interface, reusable Sets, or By func
  • Conditional logicWhen, Skip, and per-rule conditions
  • Error classificationIsValidationError, IsInternalError, IsVeraxError
  • Serializable rules — Most built-in rules implement SpecableRule; encode to JSON and rebuild at runtime via spec.Registry
  • xrr-powered — Stable codes + structured metadata out of the box

Quick Start
go get github.com/ctx42/verax
req := &CreateUserRequest{
	Name:  "A",
	Email: "bad-email",
	Age:   15,
}

err := req.Validate()

PrintError(err)
PrintJSON(err)
// Output:
// ERROR:
//
// - age: must be greater or equal to 18
// - email: must match a valid format
// - name: the length must be between 2 and 50
//
// JSON:
// {
//     "age": {
//         "code": "ECInvRange",
//         "error": "must be greater or equal to 18"
//     },
//     "email": {
//         "code": "ECInvMatch",
//         "error": "must match a valid format"
//     },
//     "name": {
//         "code": "ECInvLength",
//         "error": "the length must be between 2 and 50"
//     }
// }

Table of Contents

Installation
go get github.com/ctx42/verax

Validating Primitive Values

Use verax.Validate for single values. Stops at first failure.

err := verax.Validate(
	45,
	verax.Required,
	verax.Min(42),
	verax.Max(44),
)

PrintError(err)
PrintJSON(err)
// Output:
// ERROR:
//
// - must be less or equal to 44
//
// JSON:
// {
//     "code": "ECInvRange",
//     "error": "must be less or equal to 44"
// }

Struct Validation

verax.ValidateStruct collects all errors from every field.

err := verax.ValidateStruct(&myStruct,
	verax.Field(&myStruct.Field1, rules...),
	verax.Field(&myStruct.Field2, rules...),
)

Supports custom struct tags, Validator interface, etc.


Slices, Arrays & Maps

Full support with per-element and per-key error reporting using Each, Map, Key, etc.


Custom Rules
  • Implement verax.Rule
  • Reuse with verax.Set
  • Quick functions with verax.By

Conditional & Skipping Rules

Fine-grained control with verax.When, verax.Skip, and method chaining.


Working with Errors

All errors are xrr-powered:

  • Stable codes (ECInvRange, etc.)
  • JSON marshaling
  • Classification helpers (IsValidationError, etc.)
  • Easy inspection

Perfect for API responses and logging.


Rule Serialization

Most built-in rules implement verax.SpecableRule — they can be serialized to JSON and reconstructed at runtime. This lets you store validation configuration in a database or config file and rebuild rules on the fly.

Encoding a rule to JSON:

rule := verax.Min(18)

reg := spec.NewRegistry[verax.Rule]()
reg.RegisterBuilders(verax.Builders())

spc, _ := rule.Spec()
data, _ := reg.EncodeSpec(spc)

fmt.Println(string(data))
// Output:
// {"name":"range-rule","args":{"mode":"min","value":{"type":"int","value":18}}}

Decoding and rebuilding:

data := []byte(`{"name":"range-rule","args":{"mode":{"type":"string","value":"min"},"value":{"type":"int","value":18}}}`)

reg := spec.NewRegistry[verax.Rule]()
reg.RegisterBuilders(verax.Builders())

restored, _ := reg.DecodeAndBuild(data)

err := verax.Validate(15, restored)
fmt.Println(err)
// Output:
// must be greater or equal to 18

Set rules are serializable too — their inner rules are encoded recursively:

ageRule := verax.Set{verax.Required, verax.Min(18), verax.Max(120)}
spc, _ := ageRule.Spec()
data, _ := reg.EncodeSpec(spc)

By rule with a custom function:

By rules wrap a function reference. Register it as a named Source so it can be resolved by name during decoding:

// Register the function as a named source so it survives serialization.
src, _ := spec.NewSource("nonEmptyWord", nonEmptyWord)

reg := spec.NewRegistry[verax.Rule]()
reg.RegisterBuilders(verax.Builders())
reg.RegisterSource(src)

// Encode.
rule := verax.By(nonEmptyWord)
spc, _ := rule.Spec()
data, _ := reg.EncodeSpec(spc)

// Decode and rebuild — the function is resolved by name from the registry.
restored, _ := reg.DecodeAndBuild(data)

err := verax.Validate("hi", restored)
fmt.Println(err)
// Output:
// must be at least 3 characters long

Serializable built-ins: Absent, By, Contain, Each, Equal, Fail, In, Length, Map, Match, Noop, Required, Skip, Min/Max (via Range), and Set.

TypeRule is intentionally excluded: it holds a reflect.Type with no portable cross-language representation.


Comparison with Other Libraries
Feature ozzo-validation validator.v10 verax
Collects all errors Yes No Yes
JSON-serializable errors Manual Limited Built-in
xrr integration (codes) No No Yes
Slices/maps with details Yes Yes Yes
Conditional rules Yes Yes Yes
Serializable rules No No Yes
Simple API Good Complex Excellent

go get github.com/ctx42/verax

Full API docs → pkg.go.dev/github.com/ctx42/verax
Changelog → CHANGELOG.md

Directories

Path Synopsis
internal
test
Package test provides testing types and utilities.
Package test provides testing types and utilities.
pkg
spec
Package spec provides tools to create serializable type specifications and encoding/decoding functionality for them.
Package spec provides tools to create serializable type specifications and encoding/decoding functionality for them.
verax
Package verax provides configurable and extensible rules for validating data of various types.
Package verax provides configurable and extensible rules for validating data of various types.
verax/rule
Package rule provides an assortment of validation rules.
Package rule provides an assortment of validation rules.

Jump to

Keyboard shortcuts

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