Getting Started
This guide will help you get up and running with govalid in just a few minutes.
Installation
Install the govalid command-line tool:
1
| go install github.com/sivchari/govalid/cmd/govalid@latest
|
Verify the installation:
Basic Workflow
1. Add Validation Markers
Define your struct with validation markers in comments:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
| package main
type User struct {
// +govalid:required
Name string `json:"name"`
// +govalid:email
Email string `json:"email"`
// +govalid:gte=0
// +govalid:lte=120
Age int `json:"age"`
// +govalid:maxlength=500
Bio string `json:"bio,omitempty"`
}
|
2. Generate Validation Code
Run the govalid generator:
1
2
3
4
5
6
7
8
| # Generate for current package
govalid .
# Generate for all packages recursively
govalid ./...
# Generate for specific package
govalid ./internal/models
|
This creates validation functions and error definitions:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
| // Generated validation function
func ValidateUser(t *User) error {
if t == nil {
return ErrNilUser
}
if t.Name == "" {
return ErrNameRequiredValidation
}
if !emailRegex.MatchString(t.Email) {
return ErrEmailEmailValidation
}
if !(t.Age >= 0) {
return ErrAgeGTEValidation
}
if !(t.Age <= 120) {
return ErrAgeLTEValidation
}
if utf8.RuneCountInString(t.Bio) > 500 {
return ErrBioMaxLengthValidation
}
return nil
}
|
3. Use Generated Validation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| func main() {
user := &User{
Name: "Alice Johnson",
Email: "alice@example.com",
Age: 28,
Bio: "Software engineer passionate about Go",
}
// Validate the user
if err := ValidateUser(user); err != nil {
log.Fatalf("Validation failed: %v", err)
}
fmt.Println("User is valid!")
}
|
Error Handling
govalid generates descriptive error messages and variables:
1
2
3
4
5
6
7
8
9
| // Generated error variables
var (
ErrNilUser = errors.New("User is nil")
ErrNameRequiredValidation = errors.New("Name is required")
ErrEmailEmailValidation = errors.New("Email must be a valid email address")
ErrAgeGTEValidation = errors.New("Age must be greater than or equal to 0")
ErrAgeLTEValidation = errors.New("Age must be less than or equal to 120")
ErrBioMaxLengthValidation = errors.New("Bio must be at most 500 characters")
)
|
You can check for specific errors:
1
2
3
4
5
6
7
8
9
10
| if err := ValidateUser(user); err != nil {
switch err {
case ErrEmailEmailValidation:
fmt.Println("Please provide a valid email address")
case ErrAgeGTEValidation:
fmt.Println("Age cannot be negative")
default:
fmt.Printf("Validation error: %v\n", err)
}
}
|
Integration with Go Generate
Add a go:generate
directive to automatically run govalid:
1
2
3
4
5
6
7
| //go:generate govalid .
package main
type User struct {
// +govalid:required
Name string `json:"name"`
}
|
Then run:
Best Practices
1. Organize Validation Rules
Group related validation rules together:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
| type CreateUserRequest struct {
// Basic required fields
// +govalid:required
// +govalid:minlength=2
// +govalid:maxlength=50
Name string `json:"name"`
// Email validation
// +govalid:required
// +govalid:email
Email string `json:"email"`
// Age constraints
// +govalid:gte=13
// +govalid:lte=120
Age int `json:"age"`
}
|
2. Use Descriptive Names
Choose clear, descriptive names for your structs and fields:
1
2
3
4
5
6
7
8
9
10
| type ProductCreateRequest struct {
// +govalid:required
// +govalid:minlength=3
// +govalid:maxlength=100
ProductName string `json:"product_name"`
// +govalid:required
// +govalid:gt=0
Price float64 `json:"price"`
}
|
3. Combine with Standard Library
govalid works well with other Go validation patterns:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| func CreateUser(req *CreateUserRequest) error {
// First, validate the struct
if err := ValidateCreateUserRequest(req); err != nil {
return fmt.Errorf("validation failed: %w", err)
}
// Then, perform business logic validation
if userExists(req.Email) {
return errors.New("user already exists")
}
// Create the user
return createUser(req)
}
|
Next Steps