Golang validation framework based on static typing and generics. Designed to create complex validation rules with abilities to hook into the validation process.
This project is inspired by Symfony Validator component.
- Flexible and customizable API built in mind to use benefits of static typing and 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 implements
Validatableinterface - Customizable validation errors with translations and pluralization supported out of the box
- Easy way to create own validation rules with context propagation and message translations
This package is under active development and API may be changed until the first major version will be released. Minor
versions n 0.n.m may contain breaking changes. Patch versions m 0.n.m may contain only bug fixes.
Goals before stable release:
- implementation of static type arguments by generics;
- mechanism for asynchronous validation (lazy violations by async/await pattern);
- implement all common constraints.
go get -u github.com/muonsoft/validationValidation of string and number with typed constraints:
err := validator.Validate(context.Background(),
validation.String("not-an-email", it.IsEmail()),
validation.Number(15, it.IsGreaterThanOrEqual(18)),
)
// violations:
// This value is not a valid email address.
// This value should be 18 or more.Declarative validation with nested structs, property paths, and reusable Validatable types:
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()),
)
}
// Usage:
err := validator.ValidateIt(context.Background(), Product{
Name: "",
Tags: []string{"a", "", "a"},
Components: []Component{{Name: ""}},
})
// violations:
// 'name': This value should not be blank.
// 'tags': This collection should contain 2 elements or more.
// 'tags': This collection should contain only unique elements.
// 'tags[1]': This value should not be blank.
// 'components[0].name': This value should not be blank.See Usage for validator setup and validation arguments.
| Topic | Description |
|---|---|
| Installation | How to install the package |
| 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 |
| 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
You may help this project by
- reporting an issue;
- making translations for error messages;
- suggest an improvement or discuss the usability of the package.
If you'd like to contribute, see the contribution guide. Pull requests are welcome.
This project is licensed under the MIT License - see the LICENSE file for details.
