govalid

package module
v0.0.0-...-264534e Latest Latest
Warning

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

Go to latest
Published: Jan 8, 2026 License: MIT Imports: 0 Imported by: 0

README ΒΆ

govalid

govalid

Blazing fast, zero-allocation, type-safe validation for Go

Go Version License CI Go Report Card


πŸš€ Overview

Inspired by sivchari/govalid

govalid generates type-safe validation code from struct field markers. No reflection, no runtime overhead, just blazing fast validation.

⚑ Why govalid?

🎯 Performance Benefits

  • Zero allocations: All validation functions perform zero heap allocations
  • 5x to 44x faster: Significantly outperforms reflection-based validators
  • Compile-time optimization: Generated code is optimized by the Go compiler

πŸ‘¨β€πŸ’» Developer Experience

  • Type safety: Validation functions are generated with proper types, eliminating runtime reflection
  • Early error detection: Invalid validation rules are caught during code generation, not at runtime
  • No runtime dependencies: Generated code has minimal external dependencies

πŸ”§ Comprehensive Go Support

  • Full collection support: Maps and channels work with size validators (not supported by most libraries)
  • CEL expressions: Common Expression Language support for complex validation logic
  • Go zero-value semantics: Proper handling of Go's zero values and nil states
  • Unicode-aware: String validators properly handle Unicode characters

πŸ“Š Performance Comparison

Feature govalid Reflection Validators
Performance ~1-14ns, 0 allocs ~50-700ns, 0-5 allocs
Type Safety βœ… Generated functions ❌ Runtime reflection
Collections slice, array, map, channel slice, array only
Dependencies βœ… Minimal ❌ Heavy runtime deps
Error Detection βœ… During code generation ❌ Runtime
CEL Support βœ… Full support ❌ Limited/None

πŸ“¦ Installation

Install the govalid command-line tool by one of supported ways:

Using go install:

Defaults to latest @ and version to install specific release

go get github.com/n10ty/govalid/cmd/govalid
go install github.com/n10ty/govalid/cmd/govalid

Verify the installation:

govalid -h

🎯 Quick Start

1. Define Your Struct

// Add validation rules in struct tags
type Person struct {
    Name  string `json:"name" validate:"required"`
    Email string `json:"email" validate:"email"`
}

2. Generate Validation Code

# Generate validation code for the current directory
govalid .

# Or specify a package path
govalid ./path/to/package

# Or generate for all packages recursively
govalid ./...

This generates validation code like:

// Code generated by govalid; DO NOT EDIT.
import (
	"errors"
	"github.com/n10ty/govalid"
	govaliderrors "github.com/n10ty/govalid/validation/errors"
	"github.com/n10ty/govalid/validation/validationhelper"
)

var (
	// ErrNilPerson is returned when the Person is nil.
	ErrNilPerson = errors.New("input Person is nil")

	// ErrPersonNameRequiredValidation is returned when the Name is required but not provided.
	ErrPersonNameRequiredValidation = govaliderrors.ValidationError{Reason: "field Name is required", Path: "Person.Name", Type: "required"}

	// ErrPersonEmailEmailValidation is the error returned when the field is not a valid email address.
	ErrPersonEmailEmailValidation = govaliderrors.ValidationError{Reason: "field Email must be a valid email address", Path: "Person.Email", Type: "email"}
)

var _ govalid.Validator = (*Person)(nil)

func ValidatePerson(t *Person) error {
	if t == nil {
		return ErrNilPerson
	}

	var errs govaliderrors.ValidationErrors

	if t.Name == "" {
		err := ErrPersonNameRequiredValidation
		err.Value = t.Name
		errs = append(errs, err)
	}

	if !validationhelper.IsValidEmail(t.Email) {
		err := ErrPersonEmailEmailValidation
		err.Value = t.Email
		errs = append(errs, err)
	}

	if len(errs) > 0 {
		return errs
	}
	return nil
}

func (p *Person) Validate() error {
	return ValidatePerson(p)
}

3. Use Generated Validators

func main() {
	p := &Person{Name: "John", Email: "invalid-email"}

	if err := ValidatePerson(p); err != nil {
		log.Printf("Validation failed: %v", err)
		// Output: Validation failed: field Email must be a valid email address
		if errors.Is(err, ErrPersonEmailEmailValidation) {
			log.Printf("Email validation failed, handle error as needed: %v", err)
		}
	}
}
3.1 Handle multiple validation errors

In case of multiple validation errors, govalid generated validators will aggregate all errors and return a list of structs that implement error interface.

func main() {
	p := &Person{Name: "", Email: "invalid-email"}

	if err := ValidatePerson(p); err != nil {
		log.Printf("Validation failed: %v", err)

		if errors.Is(err, ErrPersonEmailEmailValidation) {
			log.Printf("First email error", err)
		}

		if errors.Is(err, ErrPersonNameRequiredValidation) {
			log.Printf("Second required error %v", err)
		}
	}
}
3.2 Validator Interface
func main() {
	p := &Person{Name: "John", Email: "invalid-email"}

	if err := p.Validate(); err != nil {
		log.Printf("Validation failed: %v", err)
	}
}

The generated Validate() method enables seamless integration with HTTP middleware:

import (
	"net/http"
	"github.com/n10ty/govalid/validation/middleware"
)

func CreatePersonHandler(w http.ResponseWriter, r *http.Request) {
	w.Write([]byte("OK"))
}

func main() {
	http.HandleFunc("/person", middleware.ValidateRequest[*Person](CreatePersonHandler))
	http.ListenAndServe(":8080", nil)
}

πŸ”§ Advanced Features

Multiple Validators

Apply multiple validation rules to a single field:

type User struct {
    Name  string `validate:"required,minlength=3,maxlength=50"`
    Email string `validate:"required,email"`
}

CEL Expression Support

Use Common Expression Language for complex validation:

type User struct {
    Age           int `validate:"cel=value >= 18 && value <= 120"`
    RetirementAge int `validate:"cel=value >= this.Age"`
}

Collection Support

Validate maps, channels, slices, and arrays:

type UserList struct {
    Users    []User          `validate:"maxitems=10"` // slice support
    UserMap  map[string]User `validate:"maxitems=10"` // map support  
    UserChan chan User       `validate:"maxitems=10"` // channel support
}

πŸ“ Supported Validators

govalid supports a comprehensive set of validators. For detailed documentation with examples and generated code, see MARKERS.md.

String Validators

  • required - Ensures field is not empty or nil
  • minlength - Minimum string length (Unicode-aware)
  • maxlength - Maximum string length (Unicode-aware)
  • length - Exact string length (Unicode-aware)
  • email - HTML5-compliant email validation
  • url - HTTP/HTTPS URL validation
  • uuid - RFC 4122 UUID validation
  • alpha - Alphabetic characters only
  • numeric - Numeric string validation

Numeric Validators

  • gt - Greater than
  • gte - Greater than or equal
  • lt - Less than
  • lte - Less than or equal

Collection Validators

  • minitems - Minimum collection size (slice, array, map, channel)
  • maxitems - Maximum collection size (slice, array, map, channel)

Advanced Validators

  • enum - Enumeration validation (string, numeric, custom types)
  • cel - Common Expression Language for complex validation
  • ipv4 - RFC 791-compliant IPv4 address
  • ipv6 - RFC 4291-compliant IPv6 address

πŸ“– View Complete Validator Reference β†’

πŸš€ Performance Benchmarks

govalid consistently outperforms reflection-based validators by 5x to 44x:

Validator govalid go-playground Improvement
Required 1.9ns 85.5ns 44.2x
GT/LT 1.9ns 63.0ns 32.5x
MaxLength 15.7ns 73.5ns 4.7x
Email 38.2ns 649.4ns 17.0x

All with 0 allocations vs competitors' 0-5 allocations

πŸ“Š View Complete Benchmarks

πŸ”§ Development Setup

For contributors, install lefthook to enable pre-commit checks:

make install-lefthook

Because of this, lefthook is installed, then the code-base would be checked automatically before each commit, ensuring code quality and consistency.

πŸ“„ License

MIT License - see LICENSE file for details.


Built with ❀️ for the Go community

Documentation ΒΆ

Overview ΒΆ

Package govalid provides type-safe validation code generation for structs based on markers.

Index ΒΆ

Constants ΒΆ

View Source
const Version = "1.8.0"

Version is the current version of govalid.

Variables ΒΆ

This section is empty.

Functions ΒΆ

This section is empty.

Types ΒΆ

type Validator ΒΆ

type Validator interface {
	Validate() error
}

Validator is the interface that wraps the basic Validate method. This interface is implemented automatically by generated validation code to enable middleware and other consumers to validate structs polymorphically.

Directories ΒΆ

Path Synopsis
cmd
generate-validators command
Package main is a tool to generate Go validators and their initializers
Package main is a tool to generate Go validators and their initializers
generate-validators/internal/generate
Package generate provides functions for discovering and generating validator registry files.
Package generate provides functions for discovering and generating validator registry files.
generate-validators/internal/scaffold
Package scaffold provides utilities to generate files from templates.
Package scaffold provides utilities to generate files from templates.
generate-validators/templates
Package templates provides a set of template functions for use in Go templates.
Package templates provides a set of template functions for use in Go templates.
govalid command
Package main is the entry point for the govalid command line tool.
Package main is the entry point for the govalid command line tool.
internal
analyzers/govalid
Package govalid implements type-safe validation code generation for structs based on markers.
Package govalid implements type-safe validation code generation for structs based on markers.
analyzers/markers
Package markers implements utilities for handling markers in Go code.
Package markers implements utilities for handling markers in Go code.
analyzers/registry
Package registry implements registry for analyzers.
Package registry implements registry for analyzers.
config
Package config implements configuration for govalid.
Package config implements configuration for govalid.
errors
Package errors defines all errors used in the govalid package.
Package errors defines all errors used in the govalid package.
markers
Code generated by generate-validators; DO NOT EDIT.
Code generated by generate-validators; DO NOT EDIT.
validator
Package validator implements rules for validating fields.
Package validator implements rules for validating fields.
validator/registry
Package registry provides a registry system for validators.
Package registry provides a registry system for validators.
validator/registry/initializers
Code generated by generate-validators; DO NOT EDIT.
Code generated by generate-validators; DO NOT EDIT.
validator/rules
Package rules implements validation rules for fields in structs.
Package rules implements validation rules for fields in structs.
validator/validatorhelper
Package validatorhelper provides helper functions for the govalid validator.
Package validatorhelper provides helper functions for the govalid validator.
validation
errors
Package errors provides structures for handling validation errors.
Package errors provides structures for handling validation errors.
middleware
Package middleware provides HTTP middleware for validating request payloads.
Package middleware provides HTTP middleware for validating request payloads.
validationhelper
Package validationhelper provides validation helper functions for govalid.
Package validationhelper provides validation helper functions for govalid.

Jump to

Keyboard shortcuts

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