validator

validator wraps https://github.com/go-playground/validator and adds custom validation rules, a template-based error translation engine, and a functional-options API.

Part of nurago, a collection of independent Go packages for backend services.

import "github.com/tecnickcom/nurago/pkg/validator"

Package validator wraps https://github.com/go-playground/validator and adds custom validation rules, a template-based error translation engine, and a functional-options API.

How It Works

New creates a Validator using a variadic list of Option values:

  1. An upstream vt.Validate instance is created and held internally.
  2. Options register field-name tag aliases, custom validation functions, custom type functions, and error message templates on that instance.
  3. Validator.ValidateStruct (or its context-aware twin Validator.ValidateStructCtx) runs the upstream validator and transforms any vt.ValidationErrors into an errors.Join aggregate of typed Error values, each carrying the failed tag, parameter, namespace, field name, kind, and the translated human-readable message.

Tag groups joined by “|” are iterated individually so each OR-branch failure produces an independent error.

Custom Rules

WithErrorTemplates maps a validation tag to a text/template string that receives an Error value, giving access to the namespace, field name, tag, parameter, kind, and actual value. ErrorTemplates returns a map covering the built-in go-playground/validator tags plus the custom tags. CustomValidationTags registers the custom validators:

  • falseif: conditional negation combinator
  • e164noplus: E.164 phone number without the leading ‘+’
  • zipcode: US ZIP code (12345 or 12345-6789)
  • usstate: two-letter US state code (including DC)
  • usterritory: two-letter US territory code (AS, GU, MP, PR, VI)
  • datetime_rfc3339: strict RFC-3339 datetime
  • datetime_rfc3339_relaxed: RFC-3339 with space instead of ‘T’

WithFieldNameTag (commonly “json”) makes error namespaces use the serialized field names rather than the Go struct field names. WithCustomValidationTags and WithCustomTypeFunc register project-specific rules. Every failure is an Error value.

Usage

v, err := validator.New(
    validator.WithFieldNameTag("json"),
    validator.WithCustomValidationTags(validator.CustomValidationTags()),
    validator.WithErrorTemplates(validator.ErrorTemplates()),
)
if err != nil {
    return err
}

type Address struct {
    Phone   string `json:"phone"    validate:"required,e164noplus"`
    ZIP     string `json:"zip"      validate:"required,zipcode"`
    State   string `json:"state"    validate:"required,usstate"`
}

err = v.ValidateStruct(Address{Phone: "12345", ZIP: "bad", State: "XX"})
// err is an errors.Join aggregate containing one *Error per failed field,
// each with a message like:
//   "phone must be a valid E.164 formatted phone number without the leading '+' symbol"

When To Use

  • Request payloads are validated from struct tags.
  • Error messages must be readable and templated rather than raw field paths.
  • You need validation rules beyond the built-in set.

Example

// data structure to check
validObj := RootStruct{
	BoolField: true,
	SubStr: SubStruct{
		URLField: "http://first.test.invalid",
		IntField: 3,
	},
	SubStrPtr: &SubStruct{
		URLField: "http://second.test.invalid",
		IntField: 123,
	},
	StringField: "hello world",
	NoNameField: "test",
}

// instantiate the validator object
v, err := validator.New(
	validator.WithFieldNameTag(fieldTagName),
	validator.WithCustomValidationTags(validator.CustomValidationTags()),
	validator.WithErrorTemplates(validator.ErrorTemplates()),
)
if err != nil {
	log.Fatal(err)
}

// check the data structure
err = v.ValidateStruct(validObj)
if err != nil {
	log.Fatal(err)
}

fmt.Println("OK")

// Output:
// OK

Full source is in example_validator_test.go. More runnable examples are on pkg.go.dev.

Dependencies

Importing this package pulls 8 external modules:

  • github.com/gabriel-vasile/mimetype
  • github.com/go-playground/locales
  • github.com/go-playground/universal-translator
  • github.com/go-playground/validator/v10
  • github.com/leodido/go-urn
  • golang.org/x/crypto
  • golang.org/x/sys
  • golang.org/x/text