- Notifications
You must be signed in to change notification settings - Fork12
Up to 45x faster 🚀 Auto generate type-safe validation code for structs based on markers.
License
sivchari/govalid
Folders and files
| Name | Name | Last commit message | Last commit date | |
|---|---|---|---|---|
Repository files navigation
govalid generatestype-safe validation code from struct field markers. No reflection, no runtime overhead, just blazing fast validation.
- 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
- 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
- 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
| 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 |
Install thegovalid command-line tool by one of supported ways:
Usinggo install:
go install github.com/sivchari/govalid/cmd/govalid
Or:
# Clone the repositorygit clone https://github.com/sivchari/govalid.git# Navigate to the project directorycd govalid# Install the toolgo install ./...
Verify the installation:
govalid -h
// Add validation markers above your struct// +govalid:requiredtypePersonstruct {Namestring`json:"name"`// +govalid:emailEmailstring`json:"email"`}
govalid generate
This generates validation code like:
// Code generated by govalid; DO NOT EDIT.import ("errors""github.com/sivchari/govalid"govaliderrors"github.com/sivchari/govalid/validation/errors""github.com/sivchari/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)funcValidatePerson(t*Person)error {ift==nil {returnErrNilPerson}varerrs govaliderrors.ValidationErrorsift.Name=="" {err:=ErrPersonNameRequiredValidationerr.Value=t.Nameerrs=append(errs,err)}if!validationhelper.IsValidEmail(t.Email) {err:=ErrPersonEmailEmailValidationerr.Value=t.Emailerrs=append(errs,err)}iflen(errs)>0 {returnerrs}returnnil}func (p*Person)Validate()error {returnValidatePerson(p)}
funcmain() {p:=&Person{Name:"John",Email:"invalid-email"}iferr:=ValidatePerson(p);err!=nil {log.Printf("Validation failed: %v",err)// Output: Validation failed: field Email must be a valid email addressiferrors.Is(err,ErrPersonEmailEmailValidation) {log.Printf("Email validation failed, handle error as needed: %v",err)}}}
In case of multiple validation errors,govalid generated validators will aggregate all errors and return a listof structs that implement error interface.
funcmain() {p:=&Person{Name:"",Email:"invalid-email"}iferr:=ValidatePerson(p);err!=nil {log.Printf("Validation failed: %v",err)iferrors.Is(err,ErrPersonEmailEmailValidation) {log.Printf("First email error",err)}iferrors.Is(err,ErrPersonNameRequiredValidation) {log.Printf("Second required error %v",err)}}}
funcmain() {p:=&Person{Name:"John",Email:"invalid-email"}iferr:=p.Validate();err!=nil {log.Printf("Validation failed: %v",err)}}
The generatedValidate() method enables seamless integration with HTTP middleware:
import ("net/http""github.com/sivchari/govalid/validation/middleware")funcCreatePersonHandler(w http.ResponseWriter,r*http.Request) {w.Write([]byte("OK"))}funcmain() {http.HandleFunc("/person", middleware.ValidateRequest[*Person](CreatePersonHandler))http.ListenAndServe(":8080",nil)}
Apply validation rules to entire structs:
// All fields will be validated as required// +govalid:requiredtypePersonstruct {NamestringEmailstringAgeint}
Use Common Expression Language for complex validation:
typeUserstruct {// +govalid:cel=value >= 18 && value <= 120Ageint// +govalid:cel=value >= this.AgeRetirementAgeint}
Validate maps, channels, slices, and arrays:
// +govalid:maxitems=10typeUserListstruct {Users []User// slice supportUserMapmap[string]User// map supportUserChanchanUser// channel support}
📖 View Complete Marker Reference
For a complete reference of all supported markers, seeMARKERS.md.
Core Validators:
required- Field must not be zero valuegt,gte,lt,lte- Numeric comparisonsmaxlength,minlength- String length validationmaxitems,minitems- Collection size validationenum- Enumeration validationemail,url,uuid,numeric- Format validation
Advanced:
cel- Common Expression Language support- Struct-level markers
- Custom validation logic
govalid consistently outperforms reflection-based validators by5x 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 |
38.2ns | 649.4ns | 17.0x |
All with0 allocations vs competitors' 0-5 allocations
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.
MIT License - seeLICENSE file for details.
About
Up to 45x faster 🚀 Auto generate type-safe validation code for structs based on markers.
Topics
Resources
License
Contributing
Uh oh!
There was an error while loading.Please reload this page.
Stars
Watchers
Forks
Packages0
Contributors11
Uh oh!
There was an error while loading.Please reload this page.