Package validation provides a validation library for Go.
go get -u -v github.com/gopi-frame/validation
import "github.com/gopi-frame/validation"
package main
import (
"context"
"github.com/gopi-frame/validation"
)
var user = struct {
Name string
Age int
}{
Name: "gopi",
Age: 25,
}
func main() {
validated := validation.Validate(
context.Background(),
validation.NotBlank("name", user.Name),
validation.NotBlank("age", user.Age),
validation.GreaterThan("age", user.Age, 18),
)
if validated.Fails() {
fmt.Println(validated.GetMessages())
}
}
Built-in common validator builders:
-
Generic type builders:
validation.NotBlank[T comparable]
validates if the value is not blankvalidation.Blank[T comparable]
validates if the value is blankvalidation.In[T comparable]
validates if the value is in the given listvalidation.NotIn[T comparable]
validates if the value is not in the given listvalidation.EqualTo[T comparable]
validates if the value is equal to the given valuevalidation.NotEqualTo[T comparable]
validates if the value is not equal to the given valuevalidation.LessThan[T constraints.Ordered]
validates if the value is less than the given valuevalidation.LessThanOrEqualTo[T constraints.Ordered]
validates if the value is less than or equal to the given valuevalidation.GreaterThan[T constraints.Ordered]
validates if the value is greater than the given valuevalidation.GreaterThanOrEqualTo[T constraints.Ordered]
validates if the value is greater than or equal to the given value
-
String builders:
validation.Length
validates if the length of the value is equal to the given valuevalidation.MinLength
validates if the length of the value is greater than or equal to the given valuevalidation.MaxLength
validates if the length of the value is less than or equal to the given valuevalidation.StartsWith
validates if the value starts with the given valuevalidation.StartsWithAny
validates if the value starts with any of the given valuesvalidation.EndsWith
validates if the value ends with the given valuevalidation.EndsWithAny
validates if the value ends with any of the given valuesvalidation.NotStartsWith
validates if the value does not start with the given valuevalidation.NotStartsWithAny
validates if the value does not start with any of the given valuesvalidation.NotEndsWith
validates if the value does not end with the given valuevalidation.NotEndsWithAny
validates if the value does not end with any of the given valuesvalidation.Match
validates if the value matches the given regexvalidation.NotMatch
validates if the value does not match the given regexvalidation.Contains
validates if the value contains the given valuevalidation.NotContains
validates if the value does not contain the given valuevalidation.Upper
validates if the value is uppercasevalidation.Lower
validates if the value is lowercasevalidation.Alpha
validates if the value is alphabeticvalidation.AlphaNumeric
validates if the value is alphanumericvalidation.AlphaDash
validates if the value is alphanumeric with dashes(_-)valication.Ascii
validates if the value only contains ascii charactersvalidation.AsciiNumeric
validates if the value only contains ascii characters and numbers(0-9)validation.AsciiDash
validates if the value only contains ascii characters and numbers(0-9) and dashes(_-)validation.Number
validates if the value is a numbervalidation.PositiveNumber
validates if the value is a positive numbervalidation.NegativeNumber
validates if the value is a negative numbervalidation.Integer
validates if the value is an integervalidation.PositiveInteger
validates if the value is a positive integervalidation.NegativeInteger
validates if the value is a negative integervalidation.Decimal
validates if the value is a decimalvalidation.Binary
validates if the value is a binaryvalidation.Octal
validates if the value is an octalvalidation.Hexadecimal
validates if the value is a hexadecimal
-
Time string builders:
validation.Time
validates if the value is a time in given formatvalidation.ANSIC
validates if the value is a time in ANSIC formatvalidation.UnixDate
validates if the value is a time in UnixDate formatvalidation.RubyDate
validates if the value is a time in RubyDate formatvalidation.RFC822
validates if the value is a time in RFC822 formatvalidation.RFC822Z
validates if the value is a time in RFC822Z formatvalidation.RFC850
validates if the value is a time in RFC850 formatvalidation.RFC1123
validates if the value is a time in RFC1123 formatvalidation.RFC1123Z
validates if the value is a time in RFC1123Z formatvalidation.RFC3339
validates if the value is a time in RFC3339 formatvalidation.RFC3339Nano
validates if the value is a time in RFC3339Nano formatvalidation.Kitchen
validates if the value is a time in Kitchen formatvalidation.Stamp
validates if the value is a time in Stamp formatvalidation.StampMilli
validates if the value is a time in StampMilli formatvalidation.StampMicro
validates if the value is a time in StampMicro formatvalidation.StampNano
validates if the value is a time in StampNano formatvalidation.DateTime
validates if the value is a time in DateTime formatvalidation.DateOnly
validates if the value is a date in DateOnly formatvalidation.TimeOnly
validates if the value is a time in TimeOnly formatvalidation.Duration
validates if the value is a durationvalidation.Timezone
validates if the value is a timezonevalidation.Before
validates if the time string is before the given time stringvalidation.After
validates if the time string is after the given time stringvalidation.BeforeOrEqual
validates if the time string is before or equal to the given time stringvalidation.AfterOrEqual
validates if the time string is after or equal to the given time stringvalidation.BeforeTZ
validates if the time string is before the given time string in the given timezonevalidation.AfterTZ
validates if the time string is after the given time string in the given timezonevalidation.BeforeOrEqualTZ
validates if the time string is before or equal to the given time string in the given timezonevalidation.AfterOrEqualTZ
validates if the time string is after or equal to the given time string in the given
-
Network string builders:
validation.IP
validates if the value is a valid IP addressvalidation.IPV4
validates if the value is a valid IPV4 addressvalidation.IPV6
validates if the value is a valid IPV6 addressvalidation.URL
validates if the value is a valid URLvalidation.URLWithScheme
validates if the value is a valid URL with given schemevalidation.RequestURI
validates if the value is a valid request URIvalidation.URLQuery
validates if the value is a valid URL query
-
Data string builders:
validation.JSON
validates if the value is a valid JSONvalidation.JSONArray
validates if the value is a valid JSON arrayvalidation.JSONObject
validates if the value is a valid JSON objectvalidation.JSONString
validates if the value is a valid JSON stringvalidation.UUID
validates if the value is a valid UUIDvalidation.UUIDv1
validates if the value is a valid version-1 UUIDvalidation.UUIDv2
validates if the value is a valid version-2 UUIDvalidation.UUIDv3
validates if the value is a valid version-3 UUIDvalidation.UUIDv4
validates if the value is a valid version-4 UUIDvalidation.UUIDv5
validates if the value is a valid version-5 UUIDvalidation.ULID
validates if the value is a valid ULIDvalidation.Base64
validates if the value is a valid Base64 encoded stringvalidation.Base32
validates if the value is a valid Base32 encoded string
-
Map builders:
validation.ContainsKey
validates if the map contains the given keyvalidation.ContainsValue
validates if the map contains the given value
-
Slice builders:
validation.Includes
validates if the slice contains the given valuesvalidation.Excludes
validates if the slice does not contain the given valuesvalidation.Unique
validates if the slice contains unique valuesvalidation.Count
validates if the slice contains the given number of valuesvalidation.MinCount
validates if the slice contains at least the given number of valuesvalidation.MaxCount
validates if the slice contains at most the given number of values
-
Group builders:
validation.Group[T any]
validates if the given values are valid according to the given rulesvalidation.If[T any]
validates if the given value is valid according to the given rules when the given condition is truevalidation.Each[T any]
validates if the given values' each element is valid according to the given rules when the given condition
package main
import (
"context"
"fmt"
"github.com/gopi-frame/validation"
"github.com/gopi-frame/validation/code"
)
func main() {
validator := validation.NewValidator(
validation.WithMessages(map[string]string{
code.IsNotBlank: "{{.attribute}} is required",
}), // replace the default messages with custom messages
)
// replace the default validator with the custom validator
validation.SetDefaultValidator(validator)
validated := validation.Validate(
context.Background(),
validation.NotBlank("name", "gopi"),
validation.NotBlank("age", 25),
validation.GreaterThan("age", 25, 18),
)
if validated.Fails() {
fmt.Println(validated.GetMessages())
}
}
package main
import (
"context"
"github.com/gopi-frame/validation"
"github.com/gopi-frame/validation/code"
)
var user = struct {
Name string
Age int
}{
Name: "gopi",
Age: 25,
}
func main() {
validated := validation.Validate(
context.Background(),
validation.NotBlank("name", user.Name),
validation.NotBlank("age", user.Age),
validation.GreaterThan("age", user.Age, 18),
).SetMessages(map[string]map[string]string{
"name": {
code.NotBlank: "Name is required",
},
"age": {
code.NotBlank: "Age is required",
code.GreaterThan: "Age must be greater than 18",
},
})
if validated.Fails() {
fmt.Println(validated.GetMessages())
}
}
Conditional validation is a way to validate a value against multiple rules based on a condition.
If the value is an implementation of the validation.Validatable
interface, the Validate
method of the value will be
called to validate the value first.
package main
import (
"context"
"github.com/gopi-frame/validation"
)
var user = struct {
Name string
Age int
Gender string
}{
Name: "gopi",
Age: 25,
Gender: "male",
}
func main() {
var femaleOnly = true
validated := validation.Validate(
context.Background(),
validation.NotBlank("name", user.Name),
validation.NotBlank("age", user.Age),
validation.GreaterThan("age", user.Age, 18),
validation.If(
femaleOnly,
validation.EqualTo("gender", user.Gender, "female"),
),
)
}
Group validation is a way to validate a value against multiple rules.
If the value is an implementation of the validation.Validatable
interface, the Validate
method of the value will be
called to validate the value first.
package main
import (
"context"
"github.com/gopi-frame/validation"
"github.com/gopi-frame/validation/validator"
)
var user = struct {
Name string
Age int
}{
Name: "gopi",
Age: 25,
}
func main() {
validated := validation.Validate(
context.Background(),
validation.Group("Name", user.Name, validator.IsNotBlank[string]()),
validation.Group("Age", user.Age, validator.IsNotBlank[int](), validator.IsGreaterThan[int](18)),
)
if validated.Fails() {
fmt.Println(validated.GetMessages())
}
}
package main
import (
"context"
vc "github.com/gopi-frame/contract/validation"
"github.com/gopi-frame/validation"
"github.com/gopi-frame/validation/error"
"github.com/gopi-frame/validation/validator"
)
type User struct {
Name string
Age int
}
func (u *User) Validate(ctx context.Context, _ vc.ErrorBuilder) vc.Error {
var errs = error.NewBag()
if validated := validation.Value(ctx, u.Name, validator.IsNotBlank[string]()); validated.Fails() {
errs.AddError("Name", validated)
}
if validated := validation.Value(
ctx,
u.Age,
validator.IsNotBlank[int](),
validator.IsGreaterThanOrEqualTo(18),
); validated.Fails() {
errs.AddError("Age", validated)
}
return errs
}
func main() {
var user = &User{
Name: "gopi",
Age: 25,
}
validated := validation.Validate(context.Context(), user)
if validated.Fails() {
fmt.Println(validated.GetMessages())
}
}
package main
import (
"context"
"github.com/gopi-frame/validation"
"github.com/gopi-frame/validation/validator"
)
type User struct {
Name string
Age int
}
func (u *User) Validate(ctx context.Context, _ vc.ErrorBuilder) vc.Error {
var errs = error.NewBag()
if validated := validation.Value(ctx, u.Name, validator.IsNotBlank[string]()); validated.Fails() {
errs.AddError("Name", validated)
}
if validated := validation.Value(
ctx,
u.Age,
validator.IsNotBlank[int](),
validator.IsGreaterThanOrEqualTo(18),
); validated.Fails() {
errs.AddError("Age", validated)
}
return errs
}
var users = []User{
{"gopi", 25},
{"john", 30},
{"jane", 28},
}
func main() {
validated := validation.Validate(
context.Background(),
validation.Each("age", users),
)
}
package main
import (
"context"
"fmt"
"github.com/gopi-frame/validation"
"github.com/gopi-frame/validation/code"
"github.com/gopi-frame/validation/translator"
)
func main() {
translator.RegisterTranslation("zh-CN", map[string]string{
code.IsNotBlank: "{{.attribute}}不能为空",
})
validated := validation.Validate(
validation.BindLanguage(context.Background(), "zh-CN"),
validation.NotBlank("name", ""),
validation.GreaterThan("age", 14, 18),
)
if validated.Fails() {
fmt.Println(validated.GetErrors("name").Get(code.IsNotBlank).Error()) // name不能为空
fmt.Println(validated.GetErrors("age").Get(code.GreaterThan).Error()) // age should be greater than 18.
}
}
Implement the translator.Translator
interface and register the translator by fallowing way.
validator := validation.NewValidator(
validation.WithTranslator(new(MyTranslator)),
)