Skip to content

About

Golang validation framework based on static typing and generics

Topics

Resources

Code of conduct

Contributing

Stars

18 stars

Watchers

2 watching

Forks

Latest commit

 

History

420 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Go validation library

Go Reference GitHub go.mod Go version GitHub release (latest by date) GitHub tests Go Report Card Scrutinizer Code Quality Scrutinizer Code Coverage Contributor Covenant

Validate Go values with typed, composable constraints. Define rules in code, validate nested structures, and return translated violations with property paths.

This project is inspired by Symfony Validator component.

Key features

  • Typed API using Go generics
  • Declarative style of describing a validation process in code
  • Validation of different types: booleans, numbers, strings, slices, maps, and time
  • Validation of custom data types that implement the Validatable interface
  • Customizable validation errors with translations and pluralization supported out of the box
  • Custom validation rules with context propagation and message translations

Version policy

The library is in the v0 series. Minor releases (0.x.0) may introduce breaking changes; patch releases contain bug fixes. Review the changelog before upgrading.

Quick start

Installation

Requires Go 1.24.0 or later. See Installation.

go get github.com/muonsoft/validation

Basic example

Validate a string and a number, then inspect each violation:

package main

import (
    "context"
    "fmt"
    "log"

    "github.com/muonsoft/validation"
    "github.com/muonsoft/validation/it"
    "github.com/muonsoft/validation/validator"
)

func main() {
    err := validator.Validate(context.Background(),
        validation.String("not-an-email", it.IsEmail()),
        validation.Number(15, it.IsGreaterThanOrEqual(18)),
    )
    if violations, ok := validation.UnwrapViolations(err); ok {
        for _, violation := range violations.All() {
            fmt.Println(violation.Message())
        }
    } else if err != nil {
        log.Fatal(err)
    }
}
// Output:
// This value is not a valid email address.
// This value should be greater than or equal to 18.

Conceptual example

Declarative validation with nested structs, property paths, and reusable Validatable types:

package main

import (
    "context"
    "fmt"
    "log"

    "github.com/muonsoft/validation"
    "github.com/muonsoft/validation/it"
    "github.com/muonsoft/validation/validator"
)

type Product struct {
    Name       string
    Tags       []string
    Components []Component
}

func (p Product) Validate(ctx context.Context, v *validation.Validator) error {
    return v.Validate(ctx,
        validation.StringProperty("name", p.Name, it.IsNotBlank()),
        validation.AtProperty("tags",
            validation.Countable(len(p.Tags), it.HasMinCount(2)),
            validation.Comparables[string](p.Tags, it.HasUniqueValues[string]()),
            validation.EachString(p.Tags, it.IsNotBlank()),
        ),
        validation.AtProperty("components",
            validation.Countable(len(p.Components), it.HasMinCount(1)),
            validation.ValidSlice(p.Components),
        ),
    )
}

type Component struct {
    Name string
}

func (c Component) Validate(ctx context.Context, v *validation.Validator) error {
    return v.Validate(ctx,
        validation.StringProperty("name", c.Name, it.IsNotBlank()),
    )
}

func main() {
    err := validator.ValidateIt(context.Background(), Product{
        Name: "",
        Tags: []string{"a", "", "a"},
        Components: []Component{{Name: ""}},
    })
    if violations, ok := validation.UnwrapViolations(err); ok {
        for _, violation := range violations.All() {
            fmt.Println(violation)
        }
    } else if err != nil {
        log.Fatal(err)
    }
}
// Output:
// violation at "name": "This value should not be blank."
// violation at "tags": "This collection should contain only unique elements."
// violation at "tags[1]": "This value should not be blank."
// violation at "components[0].name": "This value should not be blank."

See Usage for validator setup and validation arguments.

Documentation

Topic Description
Installation How to install the package
Constraint catalog Find constraints by input type and standalone helpers
Usage Basic concepts, validator, validation arguments
Property paths & structs Property paths, struct validation, conditional validation, groups
Violations and errors Handling violations, error structure, storing in database
Country, language & locale Formats, special codes, and application-support limitations
File uploads Names, extensions, MIME metadata, content detection, and custom detectors
UTF-8 validation Reject malformed text at input boundaries; scope and limitations
Translations Multi-language support and custom messages
Custom constraints Creating your own constraints

Full index: docs/README.md.

API reference: pkg.go.dev/github.com/muonsoft/validation

Contributing

You may help this project by

  • reporting an issue;
  • making translations for error messages;
  • suggesting an improvement or discussing the usability of the package.

If you'd like to contribute, see the contribution guide. Pull requests are welcome.

License

This project is licensed under the MIT License - see the LICENSE file for details.

About

Golang validation framework based on static typing and generics

Topics

Resources

Code of conduct

Contributing

Stars

18 stars

Watchers

2 watching

Forks

Releases

Contributors

Languages