### Install go-playground/validator Source: https://context7.com/go-playground/validator/llms.txt Install the validator library using go get. ```bash go get github.com/go-playground/validator/v10 ``` -------------------------------- ### Install Go Validator Source: https://github.com/go-playground/validator/blob/master/README.md Use go get to install the validator package. Import it into your Go code. ```go go get github.com/go-playground/validator/v10 ``` ```go import "github.com/go-playground/validator/v10" ``` -------------------------------- ### Run Tests and Linting with Make Source: https://github.com/go-playground/validator/blob/master/CLAUDE.md Use make commands to run tests with coverage and race detection, or to lint the codebase. Ensure you have Go installed and the repository cloned. ```bash make test ``` ```bash make lint ``` ```bash make bench ``` -------------------------------- ### Go Struct Validation Example Source: https://context7.com/go-playground/validator/llms.txt Demonstrates various validation tags for different data types within a Go struct. Ensure the validator instance is created and the struct is populated with data before calling Struct method. ```go package main import ( "fmt" "time" "github.com/go-playground/validator/v10" ) type ValidationExamples struct { // Required and conditional Required string `validate:"required" RequiredIf string `validate:"required_if=Required yes" RequiredUnless string `validate:"required_unless=Required no" // String validations Email string `validate:"email" URL string `validate:"url" UUID string `validate:"uuid" Alpha string `validate:"alpha" Alphanum string `validate:"alphanum" Lowercase string `validate:"lowercase" Uppercase string `validate:"uppercase" Contains string `validate:"contains=@" StartsWith string `validate:"startswith=prefix_" EndsWith string `validate:"endswith=_suffix" // Numeric validations Min int `validate:"min=10" Max int `validate:"max=100" Len string `validate:"len=5" Eq int `validate:"eq=42" Ne int `validate:"ne=0" Gt int `validate:"gt=0" Gte int `validate:"gte=1" Lt int `validate:"lt=100" Lte int `validate:"lte=99" // Choice validations OneOf string `validate:"oneof=red green blue" NoneOf string `validate:"noneof=admin root" // Format validations IP string `validate:"ip" IPv4 string `validate:"ipv4" CIDR string `validate:"cidr" MAC string `validate:"mac" Datetime string `validate:"datetime=2006-01-02" Timezone string `validate:"timezone" JSON string `validate:"json" Base64 string `validate:"base64" Hexadecimal string `validate:"hexadecimal" // Special Omitempty string `validate:"omitempty,email"` // Skip if empty Dive []int `validate:"dive,gt=0"` // Validate each element } func main() { validate := validator.New() examples := ValidationExamples{ Required: "present", Email: "test@example.com", URL: "https://example.com", UUID: "550e8400-e29b-41d4-a716-446655440000", Alpha: "abcdef", Alphanum: "abc123", Lowercase: "lowercase", Uppercase: "UPPERCASE", Contains: "user@domain", StartsWith: "prefix_value", EndsWith: "value_suffix", Min: 15, Max: 50, Len: "12345", Eq: 42, Ne: 1, Gt: 5, Gte: 1, Lt: 50, Lte: 99, OneOf: "green", NoneOf: "user", IP: "192.168.1.1", IPv4: "10.0.0.1", CIDR: "192.168.0.0/24", MAC: "00:00:5e:00:53:01", Datetime: "2024-01-15", Timezone: "America/New_York", JSON: `{"key": "value"}`, Base64: "SGVsbG8gV29ybGQ=", Hexadecimal: "1a2b3c", Omitempty: "", // Empty, so email validation skipped Dive: []int{1, 2, 3}, } err := validate.Struct(examples) if err == nil { fmt.Println("All validations passed!") } else { errs := err.(validator.ValidationErrors) for _, e := range errs { fmt.Printf("%s failed on %s\n", e.Field(), e.Tag()) } } } // Output: // All validations passed! ``` -------------------------------- ### Struct Validation Example Source: https://context7.com/go-playground/validator/llms.txt Demonstrates validating a struct with various tags, including required fields, range checks, email format, and nested struct validation. Handles validation errors by iterating through ValidationErrors. ```go package main import ( "errors" "fmt" "github.com/go-playground/validator/v10" ) type Address struct { Street string `validate:"required" City string `validate:"required" Phone string `validate:"required" } type User struct { FirstName string `validate:"required" LastName string `validate:"required" Age uint8 `validate:"gte=0,lte=130" Email string `validate:"required,email" Gender string `validate:"oneof=male female prefer_not_to" FavouriteColor string `validate:"iscolor" Addresses []*Address `validate:"required,dive,required" } var validate *validator.Validate func main() { validate = validator.New(validator.WithRequiredStructEnabled()) address := &Address{ Street: "123 Main St", City: "", // Missing required field Phone: "555-1234", } user := &User{ FirstName: "John", LastName: "Doe", Age: 135, // Exceeds max of 130 Gender: "male", Email: "john.doe@example.com", FavouriteColor: "#000", Addresses: []*Address{address}, } err := validate.Struct(user) if err != nil { var invalidValidationError *validator.InvalidValidationError if errors.As(err, &invalidValidationError) { fmt.Println("Invalid validation input:", err) return } var validateErrs validator.ValidationErrors if errors.As(err, &validateErrs) { for _, e := range validateErrs { fmt.Printf("Field: %s, Tag: %s, Value: %v\n", e.Field(), e.Tag(), e.Value()) } } } } // Output: // Field: Age, Tag: lte, Value: 135 // Field: City, Tag: required, Value: ``` -------------------------------- ### Create Validator Instance Source: https://context7.com/go-playground/validator/llms.txt Instantiate a new validator using New() and optionally enable required struct validation for recommended behavior. ```go package main import ( "fmt" "github.com/go-playground/validator/v10" ) func main() { // Create validator with recommended settings validate := validator.New(validator.WithRequiredStructEnabled()) // The validator should be used as a singleton - it caches struct info fmt.Println("Validator created successfully") } ``` -------------------------------- ### Execute Specific Tests or Benchmarks Source: https://github.com/go-playground/validator/blob/master/CLAUDE.md Target specific tests or subtests by name, or run individual benchmarks using go test commands. This is useful for focused debugging or performance analysis. ```bash go test -run TestName ./... ``` ```bash go test -run TestName/subtest_name ./... ``` ```bash go test -run=NONE -bench=BenchmarkFieldSuccess -benchmem ./... ``` -------------------------------- ### Import validator package Source: https://context7.com/go-playground/validator/llms.txt Import the validator package into your Go project. ```go import "github.com/go-playground/validator/v10" ``` -------------------------------- ### Initialize Validator with Required Struct Enabled Source: https://github.com/go-playground/validator/blob/master/README.md Initialize the validator with the WithRequiredStructEnabled option for new behavior that will be default in v11+. This is recommended for new projects. ```go validate := validator.New(validator.WithRequiredStructEnabled()) ``` -------------------------------- ### Register Validation Aliases in Go Source: https://context7.com/go-playground/validator/llms.txt Use `RegisterAlias` to create shortcuts for complex or frequently used validation tag combinations. This improves code readability and maintainability. ```go package main import ( "fmt" "github.com/go-playground/validator/v10" "strings" ) type Article struct { Title string `validate:"required,title" Content string `validate:"required,content" Slug string `validate:"required,slug" } func main() { validate := validator.New() // Register aliases for common validation patterns validate.RegisterAlias("title", "min=5,max=100") validate.RegisterAlias("content", "min=50,max=10000") validate.RegisterAlias("slug", "min=3,max=50,alphanum") // Valid article validArticle := Article{ Title: "Introduction to Go Validation", Content: strings.Repeat("This is the article content. ", 10), // 300 chars Slug: "introtogovalidation", } err := validate.Struct(validArticle) if err == nil { fmt.Println("Article is valid!") } // Invalid article invalidArticle := Article{ Title: "Hi", // Too short (< 5) Content: "Short content", // Too short (< 50) Slug: "invalid-slug!", // Contains invalid chars } err = validate.Struct(invalidArticle) if err != nil { errs := err.(validator.ValidationErrors) for _, e := range errs { fmt.Printf("Field '%s' failed on '%s' (actual: %s)\n", e.Field(), e.Tag(), e.ActualTag()) } } } // Need this import for strings.Repeat ``` -------------------------------- ### Context-Aware Validation with StructCtx in Go Source: https://context7.com/go-playground/validator/llms.txt Employ StructCtx to perform validations that depend on external context, such as database lookups or request-specific data. Register custom validation functions using RegisterValidationCtx. ```go package main import ( "context" "fmt" "github.com/go-playground/validator/v10" ) type UserRegistration struct { Username string `validate:"required,unique_username" } // Simulated database of existing usernames var existingUsers = map[string]bool{ "admin": true, "root": true, "user1": true, } func main() { validate := validator.New() // Register context-aware validation validate.RegisterValidationCtx("unique_username", func(ctx context.Context, fl validator.FieldLevel) bool { username := fl.Field().String() // Could check database, cache, or external service here // For demo, using in-memory map return !existingUsers[username] }) // Create context (could contain DB connection, request ID, etc.) ctx := context.Background() // Test with existing username reg := UserRegistration{Username: "admin"} err := validate.StructCtx(ctx, reg) if err != nil { fmt.Println("Registration failed: username 'admin' already exists") } // Test with new username reg = UserRegistration{Username: "newuser"} err = validate.StructCtx(ctx, reg) if err == nil { fmt.Println("Registration successful for 'newuser'!") } } ``` -------------------------------- ### Handle Validation Errors in Go Source: https://github.com/go-playground/validator/blob/master/README.md Check for nil errors and type cast to ValidationErrors for detailed error information. This avoids issues with errors always being non-nil. ```go err := validate.Struct(mystruct) validationErrors := err.(validator.ValidationErrors) ``` -------------------------------- ### Translate Validation Errors with i18n in Go Source: https://context7.com/go-playground/validator/llms.txt Integrate with universal-translator to provide localized error messages. Ensure the translator and default translations are registered with the validator instance. ```go package main import ( "fmt" "github.com/go-playground/locales/en" ut "github.com/go-playground/universal-translator" "github.com/go-playground/validator/v10" en_translations "github.com/go-playground/validator/v10/translations/en" ) type User struct { Username string `validate:"required,min=3" Email string `validate:"required,email" Age uint8 `validate:"gte=18,lte=65" } func main() { // Setup translator english := en.New() uni := ut.New(english, english) trans, _ := uni.GetTranslator("en") // Setup validator with translations validate := validator.New() en_translations.RegisterDefaultTranslations(validate, trans) user := User{ Username: "Jo", Email: "invalid", Age: 15, } err := validate.Struct(user) if err != nil { errs := err.(validator.ValidationErrors) // Translate all errors at once translations := errs.Translate(trans) fmt.Println("All translations:") for field, message := range translations { fmt.Printf(" %s: %s\n", field, message) } // Or translate individually fmt.Println("\nIndividual translations:") for _, e := range errs { fmt.Printf(" %s\n", e.Translate(trans)) } } } // Output: // All translations: // User.Username: Username must be at least 3 characters in length // User.Email: Email must be a valid email address // User.Age: Age must be 18 or greater // // Individual translations: // Username must be at least 3 characters in length // Email must be a valid email address // Age must be 18 or greater ``` -------------------------------- ### Register Custom Validation Functions Source: https://context7.com/go-playground/validator/llms.txt Extend the validator with custom validation logic using `RegisterValidation`. This allows you to define your own validation tags and their corresponding functions. ```go package main import ( "fmt" "github.com/go-playground/validator/v10" ) type Product struct { Name string `validate:"required,is-awesome"` Price int `validate:"required,positive-number"` } func main() { validate := validator.New() // Register custom "is-awesome" validation validate.RegisterValidation("is-awesome", func(fl validator.FieldLevel) bool { return fl.Field().String() == "awesome" }) // Register custom "positive-number" validation validate.RegisterValidation("positive-number", func(fl validator.FieldLevel) bool { return fl.Field().Int() > 0 }) // Valid product validProduct := Product{Name: "awesome", Price: 100} err := validate.Struct(validProduct) if err == nil { fmt.Println("Valid product!") } // Invalid product invalidProduct := Product{Name: "not awesome", Price: -10} err = validate.Struct(invalidProduct) if err != nil { errs := err.(validator.ValidationErrors) for _, e := range errs { fmt.Printf("Field '%s' failed on '%s' tag\n", e.Field(), e.Tag()) } } } ``` -------------------------------- ### Cross-Field Validation with `VarWithValue` Source: https://context7.com/go-playground/validator/llms.txt Use `validate.VarWithValue()` for cross-field validation, comparing one variable against another using tags like `eqfield` or `gtfield`. Ensure the second argument is the value to compare against. ```go package main import ( "fmt" "github.com/go-playground/validator/v10" ) func main() { validate := validator.New() // Password confirmation validation password := "secretPassword123" confirmPassword := "secretPassword123" err := validate.VarWithValue(password, confirmPassword, "eqfield") if err == nil { fmt.Println("Passwords match!") } // Mismatched passwords wrongConfirm := "differentPassword" err = validate.VarWithValue(password, wrongConfirm, "eqfield") if err != nil { fmt.Println("Password mismatch:", err) } // Validate that end date is after start date startDate := 10 endDate := 20 err = validate.VarWithValue(endDate, startDate, "gtfield") if err == nil { fmt.Println("End date is after start date") } } ``` -------------------------------- ### Validate Single Variable with Rules Source: https://context7.com/go-playground/validator/llms.txt Use `validate.Var()` to validate a single variable against predefined or custom validation tags. This is useful when you don't have a struct to validate. ```go package main import ( "fmt" "github.com/go-playground/validator/v10" ) func main() { validate := validator.New() // Validate email email := "invalid-email" err := validate.Var(email, "required,email") if err != nil { fmt.Println("Email validation failed:", err) } // Validate with multiple rules age := 150 err = validate.Var(age, "gte=0,lte=130") if err != nil { fmt.Println("Age validation failed:", err) } // Validate string length username := "ab" err = validate.Var(username, "required,min=3,max=20") if err != nil { fmt.Println("Username validation failed:", err) } // Valid case validEmail := "user@example.com" err = validate.Var(validEmail, "required,email") if err == nil { fmt.Println("Email is valid:", validEmail) } } ``` -------------------------------- ### Custom Type Validation for SQL Null Types Source: https://context7.com/go-playground/validator/llms.txt Handle custom types like sql.NullString and sql.NullInt64 by registering a custom type function. This ensures that the underlying values of these types are correctly validated. The provided ValidateValuer function extracts the value from driver.Valuer interfaces. ```go package main import ( "database/sql" "database/sql/driver" "fmt" "reflect" "github.com/go-playground/validator/v10" ) type DBUser struct { Name sql.NullString `validate:"required"` Age sql.NullInt64 `validate:"required,gte=0"` } func ValidateValuer(field reflect.Value) interface{} { if valuer, ok := field.Interface().(driver.Valuer); ok { val, err := valuer.Value() if err == nil { return val } } return nil } func main() { validate := validator.New() // Register custom type handler for sql.Null* types validate.RegisterCustomTypeFunc(ValidateValuer, sql.NullString{}, sql.NullInt64{}, sql.NullBool{}, sql.NullFloat64{}) // Valid user validUser := DBUser{ Name: sql.NullString{String: "John", Valid: true}, Age: sql.NullInt64{Int64: 25, Valid: true}, } err := validate.Struct(validUser) if err == nil { fmt.Println("DB User is valid!") } // Invalid user - empty name (Valid=true but empty string) invalidUser := DBUser{ Name: sql.NullString{String: "", Valid: true}, Age: sql.NullInt64{Int64: 0, Valid: false}, // NULL value } err = validate.Struct(invalidUser) if err != nil { fmt.Printf("Validation errors: %v\n", err) } } ``` -------------------------------- ### Dive Validation for Slices, Arrays, and Maps in Go Source: https://context7.com/go-playground/validator/llms.txt The 'dive' tag enables validation of elements within slices, arrays, and maps. Use 'keys' and 'endkeys' for map key validation, specifying constraints on both keys and values. ```go package main import ( "fmt" "github.com/go-playground/validator/v10" ) type Config struct { Tags []string `validate:"required,gt=0,dive,required,min=2" Settings map[string]string `validate:"required,gt=0,dive,keys,max=10,endkeys,required,max=100"` } func main() { validate := validator.New() validate.RegisterAlias("keymax", "max=10") // Valid config validConfig := Config{ Tags: []string{"go", "validator", "awesome"}, Settings: map[string]string{"theme": "dark", "lang": "en"}, } err := validate.Struct(validConfig) if err == nil { fmt.Println("Config is valid!") } // Invalid config - empty tag and long key invalidConfig := Config{ Tags: []string{"go", "", "validator"}, // Empty string fails Settings: map[string]string{"verylongkeyname": "value"}, // Key too long } err = validate.Struct(invalidConfig) if err != nil { errs := err.(validator.ValidationErrors) for _, e := range errs { fmt.Printf("Field '%s' failed on '%s' tag\n", e.Namespace(), e.Tag()) } } } ``` -------------------------------- ### Register Struct Validation Rules via Map Source: https://context7.com/go-playground/validator/llms.txt Use RegisterStructValidationMapRules to define validation rules dynamically in a map, which is useful for configurations that change at runtime. Ensure the struct fields match the map keys. ```go package main import ( "fmt" "github.com/go-playground/validator/v10" ) type Employee struct { Name string Age uint32 Email string Salary int } func main() { validate := validator.New() // Define rules dynamically via map rules := map[string]string{ "Name": "required,min=2,max=50", "Age": "required,gte=18,lte=65", "Email": "required,email", "Salary": "required,gt=0", } validate.RegisterStructValidationMapRules(rules, Employee{}) // Valid employee validEmployee := Employee{ Name: "John Doe", Age: 30, Email: "john@company.com", Salary: 50000, } err := validate.Struct(validEmployee) if err == nil { fmt.Println("Employee is valid!") } // Invalid employee invalidEmployee := Employee{ Name: "J", // Too short Age: 17, // Under 18 Email: "invalid-email", Salary: -1000, // Negative } err = validate.Struct(invalidEmployee) if err != nil { errs := err.(validator.ValidationErrors) for _, e := range errs { fmt.Printf("Field '%s' failed on '%s' tag\n", e.Field(), e.Tag()) } } } ``` -------------------------------- ### Partial Struct Validation with StructPartial in Go Source: https://context7.com/go-playground/validator/llms.txt Use `StructPartial` to validate only specified fields of a struct, ideal for scenarios like PATCH requests where only a subset of data is being updated. Ensure the validator is initialized and translations are registered. ```go package main import ( "fmt" "github.com/go-playground/validator/v10" ) type Profile struct { FirstName string `validate:"required,min=2" LastName string `validate:"required,min=2" Email string `validate:"required,email" Phone string `validate:"required" Bio string `validate:"max=500" } func main() { validate := validator.New() profile := Profile{ FirstName: "J", // Invalid - too short LastName: "", // Invalid - required Email: "valid@example.com", Phone: "", // Invalid - required Bio: "Developer", } // Only validate Email and Bio fields (for a partial update) err := validate.StructPartial(profile, "Email", "Bio") if err == nil { fmt.Println("Partial validation passed for Email and Bio!") } // Validate only FirstName - will fail err = validate.StructPartial(profile, "FirstName") if err != nil { errs := err.(validator.ValidationErrors) for _, e := range errs { fmt.Printf("Field '%s' failed: %s\n", e.Field(), e.Tag()) } } } ``` -------------------------------- ### Register Custom Validator Function Source: https://github.com/go-playground/validator/blob/master/CLAUDE.md Register a custom validation function with the validator instance. This function will be called when the corresponding tag is encountered during validation. ```go func (v *Validate) RegisterValidation(tag string, fn Func, callDepth ...uint) error { // ... implementation details ... } ``` -------------------------------- ### Register Custom Type-Based Value Extractor Source: https://github.com/go-playground/validator/blob/master/CLAUDE.md Register a custom function to extract values from specific types, such as sql.NullString or types implementing the Valuer interface. This allows the validator to handle custom data types. ```go func (v *Validate) RegisterCustomTypeFunc(fn CustomTypeFunc, types ...reflect.Type) error { // ... implementation details ... } ``` -------------------------------- ### Override Default Validation Translations in Go Source: https://context7.com/go-playground/validator/llms.txt Register custom translation messages for validators like 'required' and 'min' to provide more specific error feedback. Ensure translations are registered before validating structs. ```go package main import ( "fmt" "github.com/go-playground/locales/en" ut "github.com/go-playground/universal-translator" "github.com/go-playground/validator/v10" en_translations "github.com/go-playground/validator/v10/translations/en" ) type Account struct { Username string `validate:"required" Password string `validate:"required,min=8" } func main() { english := en.New() uni := ut.New(english, english) trans, _ := uni.GetTranslator("en") validate := validator.New() en_translations.RegisterDefaultTranslations(validate, trans) // Override the "required" translation validate.RegisterTranslation("required", trans, func(ut ut.Translator) error { return ut.Add("required", "{0} is a mandatory field!", true) }, func(ut ut.Translator, fe validator.FieldError) string { t, _ := ut.T("required", fe.Field()) return t }) // Override the "min" translation for better password message validate.RegisterTranslation("min", trans, func(ut ut.Translator) error { return ut.Add("min", "{0} must be at least {1} characters for security", true) }, func(ut ut.Translator, fe validator.FieldError) string { t, _ := ut.T("min", fe.Field(), fe.Param()) return t }) account := Account{Username: "", Password: "short"} err := validate.Struct(account) if err != nil { errs := err.(validator.ValidationErrors) for _, e := range errs { fmt.Println(e.Translate(trans)) } } } ``` -------------------------------- ### Validate Map Data Without Structs in Go Source: https://context7.com/go-playground/validator/llms.txt Use ValidateMap to validate arbitrary map data against a set of rules defined in another map, eliminating the need for explicit struct definitions for simple validation tasks. ```go package main import ( "fmt" "github.com/go-playground/validator/v10" ) func main() { validate := validator.New() // Simple map validation user := map[string]interface{}{ "name": "John Doe", "email": "john@example.com", "age": 25, } rules := map[string]interface{}{ "name": "required,min=2,max=50", "email": "required,email", "age": "required,gte=0,lte=130", } errs := validate.ValidateMap(user, rules) if len(errs) == 0 { fmt.Println("User data is valid!") } // Nested map validation data := map[string]interface{}{ "name": "Jane", "email": "jane@example.com", "details": map[string]interface{}{ "salary": "50000", "department": "Engineering", }, } nestedRules := map[string]interface{}{ "name": "required,min=2", "email": "required,email", "details": map[string]interface{}{ "salary": "required,number", "department": "required,min=2", }, } errs = validate.ValidateMap(data, nestedRules) if len(errs) == 0 { fmt.Println("Nested data is valid!") } else { fmt.Println("Validation errors:", errs) } } ``` -------------------------------- ### Excluding Fields with StructExcept in Go Source: https://context7.com/go-playground/validator/llms.txt Employ `StructExcept` to validate all fields in a struct except for those explicitly listed. This is useful for skipping fields that are managed by the system, such as timestamps, during user input validation. Ensure the validator is initialized. ```go package main import ( "fmt" "github.com/go-playground/validator/v10" ) type Document struct { Title string `validate:"required,min=5" Content string `validate:"required,min=10" Author string `validate:"required" CreatedAt string `validate:"required" UpdatedAt string `validate:"required" } func main() { validate := validator.New() // User-submitted document (system fields not yet set) doc := Document{ Title: "My Document Title", Content: "This is the document content.", Author: "John Doe", CreatedAt: "", // Will be set by system UpdatedAt: "", // Will be set by system } // Validate all fields except system-managed timestamps err := validate.StructExcept(doc, "CreatedAt", "UpdatedAt") if err == nil { fmt.Println("Document validation passed (excluding timestamps)!") } // Full validation would fail err = validate.Struct(doc) if err != nil { errs := err.(validator.ValidationErrors) fmt.Printf("Full validation found %d errors\n", len(errs)) for _, e := range errs { fmt.Printf(" - %s: %s\n", e.Field(), e.Tag()) } } } ``` -------------------------------- ### Translate Validation Errors Source: https://github.com/go-playground/validator/blob/master/CLAUDE.md Translate validation errors into human-readable messages using a provided translator. This is essential for internationalization and user-friendly error reporting. ```go func (fe FieldError) Translate(trans ut.Translator) string { // ... implementation details ... } ``` -------------------------------- ### Struct-Level Validation Reporting Source: https://github.com/go-playground/validator/blob/master/CLAUDE.md Report errors for struct-level validators using ReportError or ReportValidationErrors. This allows validators to operate on the entire struct rather than individual fields. ```go func (sl *StructLevel) ReportError(field, tag, err, param string) { // ... implementation details ... } ``` ```go func (sl *StructLevel) ReportValidationErrors(errs ValidationErrors) { // ... implementation details ... } ``` -------------------------------- ### Use JSON Field Names in Validation Errors Source: https://context7.com/go-playground/validator/llms.txt Employ RegisterTagNameFunc to make validation error messages use JSON field names instead of Go struct field names. This is particularly useful when your API uses JSON conventions. The provided function parses the 'json' struct tag. ```go package main import ( "fmt" "reflect" "strings" "github.com/go-playground/validator/v10" ) type APIRequest struct { UserName string `json:"user_name" validate:"required,min=3"` EmailAddr string `json:"email_address" validate:"required,email"` PhoneNumber string `json:"phone_number" validate:"required"` } func main() { validate := validator.New() // Register tag name function to use JSON names validate.RegisterTagNameFunc(func(fld reflect.StructField) string { name := strings.SplitN(fld.Tag.Get("json"), ",", 2)[0] if name == "-" { return "" } return name }) request := APIRequest{ UserName: "Jo", // Too short EmailAddr: "invalid-email", PhoneNumber: "", } err := validate.Struct(request) if err != nil { errs := err.(validator.ValidationErrors) for _, e := range errs { // Field() returns JSON name, StructField() returns Go name fmt.Printf("JSON field '%s' (struct: %s) failed on '%s'\n", e.Field(), e.StructField(), e.Tag()) } } } ``` -------------------------------- ### Register Custom Struct-Level Validation in Go Source: https://context7.com/go-playground/validator/llms.txt Use RegisterStructValidation to define custom validation logic that spans multiple fields within a struct. This is useful for enforcing complex relationships between fields. ```go package main import ( "fmt" "github.com/go-playground/validator/v10" ) type User struct { FirstName string `json:"fname"` LastName string `json:"lname"` Email string `validate:"required,email"` } func main() { validate := validator.New() // Register struct-level validation: either FirstName or LastName must exist validate.RegisterStructValidation(func(sl validator.StructLevel) { user := sl.Current().Interface().(User) if len(user.FirstName) == 0 && len(user.LastName) == 0 { sl.ReportError(user.FirstName, "fname", "FirstName", "fname_or_lname", "") sl.ReportError(user.LastName, "lname", "LastName", "fname_or_lname", "") } }, User{}) // User with neither first nor last name invalidUser := User{Email: "test@example.com"} err := validate.Struct(invalidUser) if err != nil { errs := err.(validator.ValidationErrors) for _, e := range errs { fmt.Printf("Field '%s' failed on '%s' tag\n", e.Field(), e.Tag()) } } // Valid user with at least one name validUser := User{FirstName: "John", Email: "john@example.com"} err = validate.Struct(validUser) if err == nil { fmt.Println("User is valid!") } } ``` -------------------------------- ### Filtered Struct Validation with StructFiltered in Go Source: https://context7.com/go-playground/validator/llms.txt Use StructFiltered to validate only specific fields of a struct that pass a provided filter function. This is useful for dynamically selecting fields for validation. ```go package main import ( "fmt" "strings" "github.com/go-playground/validator/v10" ) type Form struct { PublicName string `validate:"required,min=2" PublicEmail string `validate:"required,email" PrivateToken string `validate:"required,len=32" PrivateSecret string `validate:"required,min=16" } func main() { validate := validator.New() form := Form{ PublicName: "John", PublicEmail: "john@example.com", PrivateToken: "", // Invalid but private PrivateSecret: "", // Invalid but private } // Filter function: skip fields containing "Private" filterPrivate := func(ns []byte) bool { return strings.Contains(string(ns), "Private") } // Only validate public fields err := validate.StructFiltered(form, filterPrivate) if err == nil { fmt.Println("Public fields are valid!") } // Full validation would fail on private fields err = validate.Struct(form) if err != nil { errs := err.(validator.ValidationErrors) fmt.Printf("Full validation failed on %d fields\n", len(errs)) } } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.