xvalid is a lightweight validation library that uses methods, and can be export as JSON.
Documentation at godoc.org
Popular validation libraries like go-playground/validate and govalidator are great libraries but they suffer from a few problems.
Define rules, validate, and export as JSON:
// Store model
type Store struct {
Name string `json:"name"`
Address string `json:"address"`
Description string `json:"description"`
Tax int `json:"tax"`
Revenue int `json:"revenue"`
}
// Rules for this model.
func (store Store) Rules() xvalid.Rules {
return xvalid.New(&store).
Field(&store.Name, xvalid.MinLength(4).SetOptional().SetMessage("Please lengthen name to 4 characters or more"),
xvalid.MaxLength(80).SetMessage("Please shorten name to 80 characters or less"),
xvalid.Pattern("^[a-zA-Z0-9_]+$").SetOptional().SetMessage("Name may contain alphabets, numbers and underscores"),
xvalid.Pattern("[a-zA-Z]").SetOptional().SetMessage("Name must contain at least 1 alphabet"),
xvalid.FieldFunc(func(field []string, value any) xvalid.Error {
name := value.(string)
if name == "" {
return nil
}
if name == "admin" {
return xvalid.NewError("This name is not allowed", field)
}
return nil
})).
Field(&store.Address, xvalid.Required(), xvalid.MaxLength(120)).
Field(&store.Description, xvalid.MaxLength(1500)).
Field(&store.Tax, xvalid.Min(0), xvalid.Max(100)).
Struct(xvalid.StructFunc(func(v any) xvalid.Error {
s := v.(Store)
if s.Revenue > 1000 && s.Tax == 0 {
return xvalid.NewError("Tax cannot be empty if revenue is more than $1000", "tax")
}
return nil
}))
}
// validate
store := Store{}
err := store.Rules().Validate(store)
if err != nil {
panic(err)
}
// export rules as JSON
rules := store.Rules()
b, err := json.MarshalIndent(rules, "", " ")
if err != nil {
panic(err)
}
fmt.Println(string(b))
// generate dynamic rules
runtimeRules := xvalid.New(&store).
Field(&store.Name, xvalid.Required())
if userInput == "example" {
runtimeRules = runtimeRules.Field(&store.Address, xvalid.MinLength(getMinLength()))
}
err := runtimeRules.Validate(store)
To define your own validator, you must implement the
Validator
interface. For examples, see any of the
validators in validators.go
.