govalid

package module
v0.0.0-...-0f775b8 Latest Latest
Warning

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

Go to latest
Published: Nov 17, 2025 License: MIT Imports: 0 Imported by: 0

README ΒΆ

govalid

govalid

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

Go Version License Build Status Go Report Card


πŸš€ Overview

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 install github.com/templatedop/govalid/cmd/govalid

Or:

# Clone the repository
git clone https://github.com/templatedop/govalid.git

# Navigate to the project directory
cd govalid

# Install the tool
go install ./...

Verify the installation:

govalid -h

🎯 Quick Start

1. Define Your Struct

govalid supports two ways to define validation rules:

type Person struct {
    Name  string `json:"name" validate:"required"`
    Email string `json:"email" validate:"email"`
}
Using Comment Markers (Legacy)
type Person struct {
    // +govalid:required
    Name  string `json:"name"`
    // +govalid:email
    Email string `json:"email"`
}

Both approaches work identically. Struct tags are recommended for better integration with existing Go validation libraries.

2. Generate Validation Code

go to root of project

govalid .

This generates validation code like:

// Code generated by govalid; DO NOT EDIT.
import (
	"errors"
	"github.com/templatedop/govalid"
	govaliderrors "github.com/templatedop/govalid/validation/errors"
	"github.com/templatedop/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/templatedop/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

Struct-Level Validation

Apply validation rules to entire structs:

// Using struct tags
type Person struct {
    Name  string `validate:"required"`
    Email string `validate:"required"`
    Age   int    `validate:"required"`
}

// Or using comment markers (legacy)
// +govalid:required
type Person struct {
    Name  string
    Email string
    Age   int
}

CEL Expression Support

Use Common Expression Language for complex validation:

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

// Or using comment markers (legacy)
type User struct {
    // +govalid:cel=value >= 18 && value <= 120
    Age int
    // +govalid:cel=value >= this.Age
    RetirementAge int
}

Collection Support

Validate maps, channels, slices, and arrays:

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

// Or using comment markers (legacy)
// +govalid:maxitems=10
type UserList struct {
    Users    []User           // slice support
    UserMap  map[string]User  // map support
    UserChan chan User        // channel support
}

πŸ“ Supported Markers

πŸ“– View Complete Marker Reference

For a complete reference of all supported markers, see MARKERS.md.

Numeric Validators:

  • required - Field must not be zero value
  • gt, gte, lt, lte - Greater than, greater/equal, less than, less/equal
  • min - Minimum value (inclusive)
  • eq - Equals specific value
  • ne - Not equals specific value

String Validators:

  • maxlength, minlength, length - String length validation
  • alpha - Alphabetic characters only
  • alphanum - Alphanumeric characters only
  • lowercase - Must be all lowercase
  • oneof - Value must be one of specified options
  • containsany - Must contain any of specified characters
  • excludes - Must not contain substring
  • excludesall - Must not contain any of specified characters

Collection Validators:

  • maxitems, minitems - Collection size validation
  • unique - All elements must be unique

Format Validators:

  • email, url, uuid - Standard format validation
  • uri - URI format validation
  • fqdn - Fully Qualified Domain Name
  • ipv4, ipv6 - IP address validation
  • latitude, longitude - Geographic coordinate validation
  • iscolour - Color format (hex, rgb, rgba, hsl, hsla, named)
  • number, numeric - Numeric string validation
  • boolean - Boolean string validation

Type Validators:

  • isdefault - Must be zero/default value
  • enum - Enumeration validation

Duration Validators:

  • minduration, maxduration - Time duration constraints

Conditional Validators:

  • required_if, required_unless - Conditional required based on other field value
  • required_with, required_with_all - Required when other fields present
  • required_without, required_without_all - Required when other fields absent
  • excluded_if, excluded_unless - Conditional exclusion based on other field value
  • excluded_with, excluded_with_all - Excluded when other fields present
  • excluded_without, excluded_without_all - Excluded when other fields absent

Advanced:

  • cel - Common Expression Language support for complex expressions
  • date - Date format validation
  • Struct-level markers
  • Cross-field validation

πŸš€ 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.7.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