README
¶
ozzo-validation
Description
ozzo-validation is a Go package that provides configurable and extensible data validation capabilities. It has the following features:
- use normal programming constructs rather than error-prone struct tags to specify how data should be validated.
- can validate data of different types, e.g., structs, strings, byte slices, slices, maps, arrays.
- can validate custom data types as long as they implement the
Validatable
interface. - can validate data types that implement the
sql.Valuer
interface (e.g.sql.NullString
). - customizable and well-formatted validation errors.
- error code and message translation support.
- provide a rich set of validation rules right out of box.
- extremely easy to create and use custom validation rules.
For an example on how this library is used in an application, please refer to go-rest-api which is a starter kit for building RESTful APIs in Go.
Requirements
Go 1.13 or above.
Getting Started
The ozzo-validation package mainly includes a set of validation rules and two validation methods. You use
validation rules to describe how a value should be considered valid, and you call either validation.Validate()
or validation.ValidateStruct()
to validate the value.
Installation
Run the following command to install the package:
go get github.com/go-ozzo/ozzo-validation
Validating a Simple Value
For a simple value, such as a string or an integer, you may use validation.Validate()
to validate it. For example,
package main
import (
"fmt"
"github.com/go-ozzo/ozzo-validation/v4"
"github.com/go-ozzo/ozzo-validation/v4/is"
)
func main() {
data := "example"
err := validation.Validate(data,
validation.Required, // not empty
validation.Length(5, 100), // length between 5 and 100
is.URL, // is a valid URL
)
fmt.Println(err)
// Output:
// must be a valid URL
}
The method validation.Validate()
will run through the rules in the order that they are listed. If a rule fails
the validation, the method will return the corresponding error and skip the rest of the rules. The method will
return nil if the value passes all validation rules.
Validating a Struct
For a struct value, you usually want to check if its fields are valid. For example, in a RESTful application, you
may unmarshal the request payload into a struct and then validate the struct fields. If one or multiple fields
are invalid, you may want to get an error describing which fields are invalid. You can use validation.ValidateStruct()
to achieve this purpose. A single struct can have rules for multiple fields, and a field can be associated with multiple
rules. For example,
type Address struct {
Street string
City string
State string
Zip string
}
func (a Address) Validate() error {
return validation.ValidateStruct(&a,
// Street cannot be empty, and the length must between 5 and 50
validation.Field(&a.Street, validation.Required, validation.Length(5, 50)),
// City cannot be empty, and the length must between 5 and 50
validation.Field(&a.City, validation.Required, validation.Length(5, 50)),
// State cannot be empty, and must be a string consisting of two letters in upper case
validation.Field(&a.State, validation.Required, validation.Match(regexp.MustCompile("^[A-Z]{2}$"))),
// State cannot be empty, and must be a string consisting of five digits
validation.Field(&a.Zip, validation.Required, validation.Match(regexp.MustCompile("^[0-9]{5}$"))),
)
}
a := Address{
Street: "123",
City: "Unknown",
State: "Virginia",
Zip: "12345",
}
err := a.Validate()
fmt.Println(err)
// Output:
// Street: the length must be between 5 and 50; State: must be in a valid format.
Note that when calling validation.ValidateStruct
to validate a struct, you should pass to the method a pointer
to the struct instead of the struct itself. Similarly, when calling validation.Field
to specify the rules
for a struct field, you should use a pointer to the struct field.
When the struct validation is performed, the fields are validated in the order they are specified in ValidateStruct
.
And when each field is validated, its rules are also evaluated in the order they are associated with the field.
If a rule fails, an error is recorded for that field, and the validation will continue with the next field.
Validating a Map
Sometimes you might need to work with dynamic data stored in maps rather than a typed model. You can use validation.Map()
in this situation. A single map can have rules for multiple keys, and a key can be associated with multiple
rules. For example,
c := map[string]interface{}{
"Name": "Qiang Xue",
"Email": "q",
"Address": map[string]interface{}{
"Street": "123",
"City": "Unknown",
"State": "Virginia",
"Zip": "12345",
},
}
err := validation.Validate(c,
validation.Map(
// Name cannot be empty, and the length must be between 5 and 20.
validation.Key("Name", validation.Required, validation.Length(5, 20)),
// Email cannot be empty and should be in a valid email format.
validation.Key("Email", validation.Required, is.Email),
// Validate Address using its own validation rules
validation.Key("Address", validation.Map(
// Street cannot be empty, and the length must between 5 and 50
validation.Key("Street", validation.Required, validation.Length(5, 50)),
// City cannot be empty, and the length must between 5 and 50
validation.Key("City", validation.Required, validation.Length(5, 50)),
// State cannot be empty, and must be a string consisting of two letters in upper case
validation.Key("State", validation.Required, validation.Match(regexp.MustCompile("^[A-Z]{2}$"))),
// State cannot be empty, and must be a string consisting of five digits
validation.Key("Zip", validation.Required, validation.Match(regexp.MustCompile("^[0-9]{5}$"))),
)),
),
)
fmt.Println(err)
// Output:
// Address: (State: must be in a valid format; Street: the length must be between 5 and 50.); Email: must be a valid email address.
When the map validation is performed, the keys are validated in the order they are specified in Map
.
And when each key is validated, its rules are also evaluated in the order they are associated with the key.
If a rule fails, an error is recorded for that key, and the validation will continue with the next key.
Validation Errors
The validation.ValidateStruct
method returns validation errors found in struct fields in terms of validation.Errors
which is a map of fields and their corresponding errors. Nil is returned if validation passes.
By default, validation.Errors
uses the struct tags named json
to determine what names should be used to
represent the invalid fields. The type also implements the json.Marshaler
interface so that it can be marshaled
into a proper JSON object. For example,
type Address struct {
Street string `json:"street"`
City string `json:"city"`
State string `json:"state"`
Zip string `json:"zip"`
}
// ...perform validation here...
err := a.Validate()
b, _ := json.Marshal(err)
fmt.Println(string(b))
// Output:
// {"street":"the length must be between 5 and 50","state":"must be in a valid format"}
You may modify validation.ErrorTag
to use a different struct tag name.
If you do not like the magic that ValidateStruct
determines error keys based on struct field names or corresponding
tag values, you may use the following alternative approach:
c := Customer{
Name: "Qiang Xue",
Email: "q",
Address: Address{
State: "Virginia",
},
}
err := validation.Errors{
"name": validation.Validate(c.Name, validation.Required, validation.Length(5, 20)),
"email": validation.Validate(c.Name, validation.Required, is.Email),
"zip": validation.Validate(c.Address.Zip, validation.Required, validation.Match(regexp.MustCompile("^[0-9]{5}$"))),
}.Filter()
fmt.Println(err)
// Output:
// email: must be a valid email address; zip: cannot be blank.
In the above example, we build a validation.Errors
by a list of names and the corresponding validation results.
At the end we call Errors.Filter()
to remove from Errors
all nils which correspond to those successful validation
results. The method will return nil if Errors
is empty.
The above approach is very flexible as it allows you to freely build up your validation error structure. You can use
it to validate both struct and non-struct values. Compared to using ValidateStruct
to validate a struct,
it has the drawback that you have to redundantly specify the error keys while ValidateStruct
can automatically
find them out.
Internal Errors
Internal errors are different from validation errors in that internal errors are caused by malfunctioning code (e.g. a validator making a remote call to validate some data when the remote service is down) rather than the data being validated. When an internal error happens during data validation, you may allow the user to resubmit the same data to perform validation again, hoping the program resumes functioning. On the other hand, if data validation fails due to data error, the user should generally not resubmit the same data again.
To differentiate internal errors from validation errors, when an internal error occurs in a validator, wrap it
into validation.InternalError
by calling validation.NewInternalError()
. The user of the validator can then check
if a returned error is an internal error or not. For example,
if err := a.Validate(); err != nil {
if e, ok := err.(validation.InternalError); ok {
// an internal error happened
fmt.Println(e.InternalError())
}
}
Validatable Types
A type is validatable if it implements the validation.Validatable
interface.
When validation.Validate
is used to validate a validatable value, if it does not find any error with the
given validation rules, it will further call the value's Validate()
method.
Similarly, when validation.ValidateStruct
is validating a struct field whose type is validatable, it will call
the field's Validate
method after it passes the listed rules.
Note: When implementing
validation.Validatable
, do not callvalidation.Validate()
to validate the value in its original type because this will cause infinite loops. For example, if you define a new typeMyString
asstring
and implementvalidation.Validatable
forMyString
, within theValidate()
function you should cast the value tostring
first before callingvalidation.Validate()
to validate it.
In the following example, the Address
field of Customer
is validatable because Address
implements
validation.Validatable
. Therefore, when validating a Customer
struct with validation.ValidateStruct
,
validation will "dive" into the Address
field.
type Customer struct {
Name string
Gender string
Email string
Address Address
}
func (c Customer) Validate() error {
return validation.ValidateStruct(&c,
// Name cannot be empty, and the length must be between 5 and 20.
validation.Field(&c.Name, validation.Required, validation.Length(5, 20)),
// Gender is optional, and should be either "Female" or "Male".
validation.Field(&c.Gender, validation.In("Female", "Male")),
// Email cannot be empty and should be in a valid email format.
validation.Field(&c.Email, validation.Required, is.Email),
// Validate Address using its own validation rules
validation.Field(&c.Address),
)
}
c := Customer{
Name: "Qiang Xue",
Email: "q",
Address: Address{
Street: "123 Main Street",
City: "Unknown",
State: "Virginia",
Zip: "12345",
},
}
err := c.Validate()
fmt.Println(err)
// Output:
// Address: (State: must be in a valid format.); Email: must be a valid email address.
Sometimes, you may want to skip the invocation of a type's Validate
method. To do so, simply associate
a validation.Skip
rule with the value being validated.
Maps/Slices/Arrays of Validatables
When validating an iterable (map, slice, or array), whose element type implements the validation.Validatable
interface,
the validation.Validate
method will call the Validate
method of every non-nil element.
The validation errors of the elements will be returned as validation.Errors
which maps the keys of the
invalid elements to their corresponding validation errors. For example,
addresses := []Address{
Address{State: "MD", Zip: "12345"},
Address{Street: "123 Main St", City: "Vienna", State: "VA", Zip: "12345"},
Address{City: "Unknown", State: "NC", Zip: "123"},
}
err := validation.Validate(addresses)
fmt.Println(err)
// Output:
// 0: (City: cannot be blank; Street: cannot be blank.); 2: (Street: cannot be blank; Zip: must be in a valid format.).
When using validation.ValidateStruct
to validate a struct, the above validation procedure also applies to those struct
fields which are map/slices/arrays of validatables.
Each
The Each
validation rule allows you to apply a set of rules to each element of an array, slice, or map.
type Customer struct {
Name string
Emails []string
}
func (c Customer) Validate() error {
return validation.ValidateStruct(&c,
// Name cannot be empty, and the length must be between 5 and 20.
validation.Field(&c.Name, validation.Required, validation.Length(5, 20)),
// Emails are optional, but if given must be valid.
validation.Field(&c.Emails, validation.Each(is.Email)),
)
}
c := Customer{
Name: "Qiang Xue",
Emails: []Email{
"valid@example.com",
"invalid",
},
}
err := c.Validate()
fmt.Println(err)
// Output:
// Emails: (1: must be a valid email address.).
Pointers
When a value being validated is a pointer, most validation rules will validate the actual value pointed to by the pointer. If the pointer is nil, these rules will skip the validation.
An exception is the validation.Required
and validation.NotNil
rules. When a pointer is nil, they
will report a validation error.
Types Implementing sql.Valuer
If a data type implements the sql.Valuer
interface (e.g. sql.NullString
), the built-in validation rules will handle
it properly. In particular, when a rule is validating such data, it will call the Value()
method and validate
the returned value instead.
Required vs. Not Nil
When validating input values, there are two different scenarios about checking if input values are provided or not.
In the first scenario, an input value is considered missing if it is not entered or it is entered as a zero value
(e.g. an empty string, a zero integer). You can use the validation.Required
rule in this case.
In the second scenario, an input value is considered missing only if it is not entered. A pointer field is usually
used in this case so that you can detect if a value is entered or not by checking if the pointer is nil or not.
You can use the validation.NotNil
rule to ensure a value is entered (even if it is a zero value).
Embedded Structs
The validation.ValidateStruct
method will properly validate a struct that contains embedded structs. In particular,
the fields of an embedded struct are treated as if they belong directly to the containing struct. For example,
type Employee struct {
Name string
}
type Manager struct {
Employee
Level int
}
m := Manager{}
err := validation.ValidateStruct(&m,
validation.Field(&m.Name, validation.Required),
validation.Field(&m.Level, validation.Required),
)
fmt.Println(err)
// Output:
// Level: cannot be blank; Name: cannot be blank.
In the above code, we use &m.Name
to specify the validation of the Name
field of the embedded struct Employee
.
And the validation error uses Name
as the key for the error associated with the Name
field as if Name
a field
directly belonging to Manager
.
If Employee
implements the validation.Validatable
interface, we can also use the following code to validate
Manager
, which generates the same validation result:
func (e Employee) Validate() error {
return validation.ValidateStruct(&e,
validation.Field(&e.Name, validation.Required),
)
}
err := validation.ValidateStruct(&m,
validation.Field(&m.Employee),
validation.Field(&m.Level, validation.Required),
)
fmt.Println(err)
// Output:
// Level: cannot be blank; Name: cannot be blank.
Conditional Validation
Sometimes, we may want to validate a value only when certain condition is met. For example, we want to ensure the
unit
struct field is not empty only when the quantity
field is not empty; or we may want to ensure either email
or phone
is provided. The so-called conditional validation can be achieved with the help of validation.When
.
The following code implements the aforementioned examples:
result := validation.ValidateStruct(&a,
validation.Field(&a.Unit, validation.When(a.Quantity != "", validation.Required).Else(validation.Nil)),
validation.Field(&a.Phone, validation.When(a.Email == "", validation.Required.Error('Either phone or Email is required.')),
validation.Field(&a.Email, validation.When(a.Phone == "", validation.Required.Error('Either phone or Email is required.')),
)
Note that validation.When
and validation.When.Else
can take a list of validation rules. These rules will be executed only when the condition is true (When) or false (Else).
The above code can also be simplified using the shortcut validation.Required.When
:
result := validation.ValidateStruct(&a,
validation.Field(&a.Unit, validation.Required.When(a.Quantity != ""), validation.Nil.When(a.Quantity == "")),
validation.Field(&a.Phone, validation.Required.When(a.Email == "").Error('Either phone or Email is required.')),
validation.Field(&a.Email, validation.Required.When(a.Phone == "").Error('Either phone or Email is required.')),
)
Customizing Error Messages
All built-in validation rules allow you to customize their error messages. To do so, simply call the Error()
method
of the rules. For example,
data := "2123"
err := validation.Validate(data,
validation.Required.Error("is required"),
validation.Match(regexp.MustCompile("^[0-9]{5}$")).Error("must be a string with five digits"),
)
fmt.Println(err)
// Output:
// must be a string with five digits
You can also customize the pre-defined error(s) of a built-in rule such that the customization applies to every
instance of the rule. For example, the Required
rule uses the pre-defined error ErrRequired
. You can customize it
during the application initialization:
validation.ErrRequired = validation.ErrRequired.SetMessage("the value is required")
Error Code and Message Translation
The errors returned by the validation rules implement the Error
interface which contains the Code()
method
to provide the error code information. While the message of a validation error is often customized, the code is immutable.
You can use error code to programmatically check a validation error or look for the translation of the corresponding message.
If you are developing your own validation rules, you can use validation.NewError()
to create a validation error which
implements the aforementioned Error
interface.
Creating Custom Rules
Creating a custom rule is as simple as implementing the validation.Rule
interface. The interface contains a single
method as shown below, which should validate the value and return the validation error, if any:
// Validate validates a value and returns an error if validation fails.
Validate(value interface{}) error
If you already have a function with the same signature as shown above, you can call validation.By()
to turn
it into a validation rule. For example,
func checkAbc(value interface{}) error {
s, _ := value.(string)
if s != "abc" {
return errors.New("must be abc")
}
return nil
}
err := validation.Validate("xyz", validation.By(checkAbc))
fmt.Println(err)
// Output: must be abc
If your validation function takes additional parameters, you can use the following closure trick:
func stringEquals(str string) validation.RuleFunc {
return func(value interface{}) error {
s, _ := value.(string)
if s != str {
return errors.New("unexpected string")
}
return nil
}
}
err := validation.Validate("xyz", validation.By(stringEquals("abc")))
fmt.Println(err)
// Output: unexpected string
Rule Groups
When a combination of several rules are used in multiple places, you may use the following trick to create a rule group so that your code is more maintainable.
var NameRule = []validation.Rule{
validation.Required,
validation.Length(5, 20),
}
type User struct {
FirstName string
LastName string
}
func (u User) Validate() error {
return validation.ValidateStruct(&u,
validation.Field(&u.FirstName, NameRule...),
validation.Field(&u.LastName, NameRule...),
)
}
In the above example, we create a rule group NameRule
which consists of two validation rules. We then use this rule
group to validate both FirstName
and LastName
.
Context-aware Validation
While most validation rules are self-contained, some rules may depend dynamically on a context. A rule may implement the
validation.RuleWithContext
interface to support the so-called context-aware validation.
To validate an arbitrary value with a context, call validation.ValidateWithContext()
. The context.Conext
parameter
will be passed along to those rules that implement validation.RuleWithContext
.
To validate the fields of a struct with a context, call validation.ValidateStructWithContext()
.
You can define a context-aware rule from scratch by implementing both validation.Rule
and validation.RuleWithContext
.
You can also use validation.WithContext()
to turn a function into a context-aware rule. For example,
rule := validation.WithContext(func(ctx context.Context, value interface{}) error {
if ctx.Value("secret") == value.(string) {
return nil
}
return errors.New("value incorrect")
})
value := "xyz"
ctx := context.WithValue(context.Background(), "secret", "example")
err := validation.ValidateWithContext(ctx, value, rule)
fmt.Println(err)
// Output: value incorrect
When performing context-aware validation, if a rule does not implement validation.RuleWithContext
, its
validation.Rule
will be used instead.
Built-in Validation Rules
The following rules are provided in the validation
package:
In(...interface{})
: checks if a value can be found in the given list of values.NotIn(...interface{})
: checks if a value is NOT among the given list of values.Length(min, max int)
: checks if the length of a value is within the specified range. This rule should only be used for validating strings, slices, maps, and arrays.RuneLength(min, max int)
: checks if the length of a string is within the specified range. This rule is similar asLength
except that when the value being validated is a string, it checks its rune length instead of byte length.Min(min interface{})
andMax(max interface{})
: checks if a value is within the specified range. These two rules should only be used for validating int, uint, float and time.Time types.Match(*regexp.Regexp)
: checks if a value matches the specified regular expression. This rule should only be used for strings and byte slices.Date(layout string)
: checks if a string value is a date whose format is specified by the layout. By callingMin()
and/orMax()
, you can check additionally if the date is within the specified range.Required
: checks if a value is not empty (neither nil nor zero).NotNil
: checks if a pointer value is not nil. Non-pointer values are considered valid.NilOrNotEmpty
: checks if a value is a nil pointer or a non-empty value. This differs fromRequired
in that it treats a nil pointer as valid.Nil
: checks if a value is a nil pointer.Empty
: checks if a value is empty. nil pointers are considered valid.Skip
: this is a special rule used to indicate that all rules following it should be skipped (including the nested ones).MultipleOf
: checks if the value is a multiple of the specified range.Each(rules ...Rule)
: checks the elements within an iterable (map/slice/array) with other rules.When(condition, rules ...Rule)
: validates with the specified rules only when the condition is true.Else(rules ...Rule)
: must be used withWhen(condition, rules ...Rule)
, validates with the specified rules only when the condition is false.
The is
sub-package provides a list of commonly used string validation rules that can be used to check if the format
of a value satisfies certain requirements. Note that these rules only handle strings and byte slices and if a string
or byte slice is empty, it is considered valid. You may use a Required
rule to ensure a value is not empty.
Below is the whole list of the rules provided by the is
package:
Email
: validates if a string is an email or not. It also checks if the MX record exists for the email domain.EmailFormat
: validates if a string is an email or not. It does NOT check the existence of the MX record.URL
: validates if a string is a valid URLRequestURL
: validates if a string is a valid request URLRequestURI
: validates if a string is a valid request URIAlpha
: validates if a string contains English letters only (a-zA-Z)Digit
: validates if a string contains digits only (0-9)Alphanumeric
: validates if a string contains English letters and digits only (a-zA-Z0-9)UTFLetter
: validates if a string contains unicode letters onlyUTFDigit
: validates if a string contains unicode decimal digits onlyUTFLetterNumeric
: validates if a string contains unicode letters and numbers onlyUTFNumeric
: validates if a string contains unicode number characters (category N) onlyLowerCase
: validates if a string contains lower case unicode letters onlyUpperCase
: validates if a string contains upper case unicode letters onlyHexadecimal
: validates if a string is a valid hexadecimal numberHexColor
: validates if a string is a valid hexadecimal color codeRGBColor
: validates if a string is a valid RGB color in the form of rgb(R, G, B)Int
: validates if a string is a valid integer numberFloat
: validates if a string is a floating point numberUUIDv3
: validates if a string is a valid version 3 UUIDUUIDv4
: validates if a string is a valid version 4 UUIDUUIDv5
: validates if a string is a valid version 5 UUIDUUID
: validates if a string is a valid UUIDCreditCard
: validates if a string is a valid credit card numberISBN10
: validates if a string is an ISBN version 10ISBN13
: validates if a string is an ISBN version 13ISBN
: validates if a string is an ISBN (either version 10 or 13)JSON
: validates if a string is in valid JSON formatASCII
: validates if a string contains ASCII characters onlyPrintableASCII
: validates if a string contains printable ASCII characters onlyMultibyte
: validates if a string contains multibyte charactersFullWidth
: validates if a string contains full-width charactersHalfWidth
: validates if a string contains half-width charactersVariableWidth
: validates if a string contains both full-width and half-width charactersBase64
: validates if a string is encoded in Base64DataURI
: validates if a string is a valid base64-encoded data URIE164
: validates if a string is a valid E164 phone number (+19251232233)CountryCode2
: validates if a string is a valid ISO3166 Alpha 2 country codeCountryCode3
: validates if a string is a valid ISO3166 Alpha 3 country codeDialString
: validates if a string is a valid dial string that can be passed to Dial()MAC
: validates if a string is a MAC addressIP
: validates if a string is a valid IP address (either version 4 or 6)IPv4
: validates if a string is a valid version 4 IP addressIPv6
: validates if a string is a valid version 6 IP addressSubdomain
: validates if a string is valid subdomainDomain
: validates if a string is valid domainDNSName
: validates if a string is valid DNS nameHost
: validates if a string is a valid IP (both v4 and v6) or a valid DNS namePort
: validates if a string is a valid port numberMongoID
: validates if a string is a valid Mongo IDLatitude
: validates if a string is a valid latitudeLongitude
: validates if a string is a valid longitudeSSN
: validates if a string is a social security number (SSN)Semver
: validates if a string is a valid semantic version
Credits
The is
sub-package wraps the excellent validators provided by the govalidator package.
Documentation
¶
Overview ¶
Package validation provides configurable and extensible rules for validating data of various types.
Example ¶
Output: Address: (State: must be in a valid format.); Email: must be a valid email address.
Example (Five) ¶
Output: Level: cannot be blank; Name: cannot be blank.
Example (Four) ¶
Output: email: must be a valid email address; zip: cannot be blank.
Example (Second) ¶
Output: must be a valid URL
Example (Seven) ¶
Output: Address: (State: must be in a valid format; Street: the length must be between 5 and 50.); Email: must be a valid email address.
Example (Six) ¶
Output: unexpected value <nil>
Example (Third) ¶
Output: 0: (City: cannot be blank; Street: cannot be blank.); 2: (Street: cannot be blank; Zip: must be in a valid format.).
Index ¶
- Variables
- func EnsureString(value interface{}) (string, error)
- func Indirect(value interface{}) (interface{}, bool)
- func IsEmpty(value interface{}) bool
- func LengthOfValue(value interface{}) (int, error)
- func StringOrBytes(value interface{}) (isString bool, str string, isBytes bool, bs []byte)
- func ToFloat(value interface{}) (float64, error)
- func ToInt(value interface{}) (int64, error)
- func ToUint(value interface{}) (uint64, error)
- func Validate(value interface{}, rules ...Rule) error
- func ValidateStruct(structPtr interface{}, fields ...*FieldRules) error
- func ValidateStructWithContext(ctx context.Context, structPtr interface{}, fields ...*FieldRules) error
- func ValidateWithContext(ctx context.Context, value interface{}, rules ...Rule) error
- type DateRule
- func (r DateRule) Error(message string) DateRule
- func (r DateRule) ErrorObject(err Error) DateRule
- func (r DateRule) Max(max time.Time) DateRule
- func (r DateRule) Min(min time.Time) DateRule
- func (r DateRule) RangeError(message string) DateRule
- func (r DateRule) RangeErrorObject(err Error) DateRule
- func (r DateRule) Validate(value interface{}) error
- type EachRule
- type ErrFieldNotFound
- type ErrFieldPointer
- type Error
- type ErrorObject
- func (e ErrorObject) AddParam(name string, value interface{}) Error
- func (e ErrorObject) Code() string
- func (e ErrorObject) Error() string
- func (e ErrorObject) Message() string
- func (e ErrorObject) Params() map[string]interface{}
- func (e ErrorObject) SetCode(code string) Error
- func (e ErrorObject) SetMessage(message string) Error
- func (e ErrorObject) SetParams(params map[string]interface{}) Error
- type Errors
- type FieldRules
- type InRule
- type InternalError
- type KeyRules
- type LengthRule
- type MapRule
- type MatchRule
- type MultipleOfRule
- type NotInRule
- type RequiredRule
- type Rule
- type RuleFunc
- type RuleWithContext
- type RuleWithContextFunc
- type StringRule
- type ThresholdRule
- type Validatable
- type ValidatableWithContext
- type WhenRule
Examples ¶
Constants ¶
This section is empty.
Variables ¶
var ( // ErrNil is the error that returns when a value is not nil. ErrNil = NewError("validation_nil", "must be blank") // ErrEmpty is the error that returns when a not nil value is not empty. ErrEmpty = NewError("validation_empty", "must be blank") )
var ( // ErrDateInvalid is the error that returns in case of an invalid date. ErrDateInvalid = NewError("validation_date_invalid", "must be a valid date") // ErrDateOutOfRange is the error that returns in case of an invalid date. ErrDateOutOfRange = NewError("validation_date_out_of_range", "the date is out of range") )
var ( // ErrLengthTooLong is the error that returns in case of too long length. ErrLengthTooLong = NewError("validation_length_too_long", "the length must be no more than {{.max}}") // ErrLengthTooShort is the error that returns in case of too short length. ErrLengthTooShort = NewError("validation_length_too_short", "the length must be no less than {{.min}}") // ErrLengthInvalid is the error that returns in case of an invalid length. ErrLengthInvalid = NewError("validation_length_invalid", "the length must be exactly {{.min}}") // ErrLengthOutOfRange is the error that returns in case of out of range length. ErrLengthOutOfRange = NewError("validation_length_out_of_range", "the length must be between {{.min}} and {{.max}}") // ErrLengthEmptyRequired is the error that returns in case of non-empty value. ErrLengthEmptyRequired = NewError("validation_length_empty_required", "the value must be empty") )
var ( // ErrNotMap is the error that the value being validated is not a map. ErrNotMap = errors.New("only a map can be validated") // ErrKeyWrongType is the error returned in case of an incorrect key type. ErrKeyWrongType = NewError("validation_key_wrong_type", "key not the correct type") // ErrKeyMissing is the error returned in case of a missing key. ErrKeyMissing = NewError("validation_key_missing", "required key is missing") // ErrKeyUnexpected is the error returned in case of an unexpected key. ErrKeyUnexpected = NewError("validation_key_unexpected", "key not expected") )
var ( // ErrMinGreaterEqualThanRequired is the error that returns when a value is less than a specified threshold. ErrMinGreaterEqualThanRequired = NewError("validation_min_greater_equal_than_required", "must be no less than {{.threshold}}") // ErrMaxLessEqualThanRequired is the error that returns when a value is greater than a specified threshold. ErrMaxLessEqualThanRequired = NewError("validation_max_less_equal_than_required", "must be no greater than {{.threshold}}") // ErrMinGreaterThanRequired is the error that returns when a value is less than or equal to a specified threshold. ErrMinGreaterThanRequired = NewError("validation_min_greater_than_required", "must be greater than {{.threshold}}") // ErrMaxLessThanRequired is the error that returns when a value is greater than or equal to a specified threshold. ErrMaxLessThanRequired = NewError("validation_max_less_than_required", "must be less than {{.threshold}}") )
var ( // ErrRequired is the error that returns when a value is required. ErrRequired = NewError("validation_required", "cannot be blank") // ErrNilOrNotEmpty is the error that returns when a value is not nil and is empty. ErrNilOrNotEmpty = NewError("validation_nil_or_not_empty_required", "cannot be blank") )
var ( // ErrorTags is the struct tag name used to customize the error field name for a struct field. ErrorTags = []string{"json", "query", "path", "header", "ctx"} // Skip is a special validation rule that indicates all rules following it should be skipped. Skip = skipRule{/* contains filtered or unexported fields */} )
var Empty = absentRule{/* contains filtered or unexported fields */}
Empty checks if a not nil value is empty.
var ErrInInvalid = NewError("validation_in_invalid", "must be a valid value")
ErrInInvalid is the error that returns in case of an invalid value for "in" rule.
var ErrMatchInvalid = NewError("validation_match_invalid", "must be in a valid format")
ErrMatchInvalid is the error that returns in case of invalid format.
var ErrMultipleOfInvalid = NewError("validation_multiple_of_invalid", "must be multiple of {{.base}}")
ErrMultipleOfInvalid is the error that returns when a value is not multiple of a base.
var ErrNotInInvalid = NewError("validation_not_in_invalid", "must not be in list")
ErrNotInInvalid is the error that returns when a value is in a list.
var ErrNotNilRequired = NewError("validation_not_nil_required", "is required")
ErrNotNilRequired is the error that returns when a value is Nil.
var ( // ErrStructPointer is the error that a struct being validated is not specified as a pointer. ErrStructPointer = errors.New("only a pointer to a struct can be validated") )
var Nil = absentRule{/* contains filtered or unexported fields */}
Nil is a validation rule that checks if a value is nil. It is the opposite of NotNil rule
var NilOrNotEmpty = RequiredRule{/* contains filtered or unexported fields */}
NilOrNotEmpty checks if a value is a nil pointer or a value that is not empty. NilOrNotEmpty differs from Required in that it treats a nil pointer as valid.
var NotNil = notNilRule{}
NotNil is a validation rule that checks if a value is not nil. NotNil only handles types including interface, pointer, slice, and map. All other types are considered valid.
var Required = RequiredRule{/* contains filtered or unexported fields */}
Required is a validation rule that checks if a value is not empty. A value is considered not empty if - integer, float: not zero - bool: true - string, array, slice, map: len() > 0 - interface, pointer: not nil and the referenced value is not empty - any other types
Functions ¶
func EnsureString ¶
EnsureString ensures the given value is a string. If the value is a byte slice, it will be typecast into a string. An error is returned otherwise.
func Indirect ¶
func Indirect(value interface{}) (interface{}, bool)
Indirect returns the value that the given interface or pointer references to. If the value implements driver.Valuer, it will deal with the value returned by the Value() method instead. A boolean value is also returned to indicate if the value is nil or not (only applicable to interface, pointer, map, and slice). If the value is neither an interface nor a pointer, it will be returned back.
func IsEmpty ¶
func IsEmpty(value interface{}) bool
IsEmpty checks if a value is empty or not. A value is considered empty if - integer, float: zero - bool: false - string, array: len() == 0 - slice, map: nil or len() == 0 - interface, pointer: nil or the referenced value is empty
func LengthOfValue ¶
LengthOfValue returns the length of a value that is a string, slice, map, or array. An error is returned for all other types.
func StringOrBytes ¶
StringOrBytes typecasts a value into a string or byte slice. Boolean flags are returned to indicate if the typecasting succeeds or not.
func ToFloat ¶
ToFloat converts the given value to a float64. An error is returned for all incompatible types.
func ToInt ¶
ToInt converts the given value to an int64. An error is returned for all incompatible types.
func ToUint ¶
ToUint converts the given value to an uint64. An error is returned for all incompatible types.
func Validate ¶
Validate validates the given value and returns the validation error, if any.
Validate performs validation using the following steps:
- For each rule, call its `Validate()` to validate the value. Return if any error is found.
- If the value being validated implements `Validatable`, call the value's `Validate()`. Return with the validation result.
- If the value being validated is a map/slice/array, and the element type implements `Validatable`, for each element call the element value's `Validate()`. Return with the validation result.
func ValidateStruct ¶
func ValidateStruct(structPtr interface{}, fields ...*FieldRules) error
ValidateStruct validates a struct by checking the specified struct fields against the corresponding validation rules. Note that the struct being validated must be specified as a pointer to it. If the pointer is nil, it is considered valid. Use Field() to specify struct fields that need to be validated. Each Field() call specifies a single field which should be specified as a pointer to the field. A field can be associated with multiple rules. For example,
value := struct { Name string Value string }{"name", "demo"} err := validation.ValidateStruct(&value, validation.Field(&a.Name, validation.Required), validation.Field(&a.Value, validation.Required, validation.Length(5, 10)), ) fmt.Println(err) // Value: the length must be between 5 and 10.
An error will be returned if validation fails.
func ValidateStructWithContext ¶
func ValidateStructWithContext(ctx context.Context, structPtr interface{}, fields ...*FieldRules) error
ValidateStructWithContext validates a struct with the given context. The only difference between ValidateStructWithContext and ValidateStruct is that the former will validate struct fields with the provided context. Please refer to ValidateStruct for the detailed instructions on how to use this function.
func ValidateWithContext ¶
ValidateWithContext validates the given value with the given context and returns the validation error, if any.
ValidateWithContext performs validation using the following steps:
- For each rule, call its `ValidateWithContext()` to validate the value if the rule implements `RuleWithContext`. Otherwise call `Validate()` of the rule. Return if any error is found.
- If the value being validated implements `ValidatableWithContext`, call the value's `ValidateWithContext()` and return with the validation result.
- If the value being validated implements `Validatable`, call the value's `Validate()` and return with the validation result.
- If the value being validated is a map/slice/array, and the element type implements `ValidatableWithContext`, for each element call the element value's `ValidateWithContext()`. Return with the validation result.
- If the value being validated is a map/slice/array, and the element type implements `Validatable`, for each element call the element value's `Validate()`. Return with the validation result.
Types ¶
type DateRule ¶
type DateRule struct {
// contains filtered or unexported fields
}
DateRule is a validation rule that validates date/time string values.
func Date ¶
Date returns a validation rule that checks if a string value is in a format that can be parsed into a date. The format of the date should be specified as the layout parameter which accepts the same value as that for time.Parse. For example,
validation.Date(time.ANSIC) validation.Date("02 Jan 06 15:04 MST") validation.Date("2006-01-02")
By calling Min() and/or Max(), you can let the Date rule to check if a parsed date value is within the specified date range.
An empty value is considered valid. Use the Required rule to make sure a value is not empty.
func (DateRule) Error ¶
Error sets the error message that is used when the value being validated is not a valid date.
func (DateRule) ErrorObject ¶
ErrorObject sets the error struct that is used when the value being validated is not a valid date..
func (DateRule) Max ¶
Max sets the maximum date range. A zero value means skipping the maximum range validation.
func (DateRule) Min ¶
Min sets the minimum date range. A zero value means skipping the minimum range validation.
func (DateRule) RangeError ¶
RangeError sets the error message that is used when the value being validated is out of the specified Min/Max date range.
func (DateRule) RangeErrorObject ¶
RangeErrorObject sets the error struct that is used when the value being validated is out of the specified Min/Max date range.
type EachRule ¶
type EachRule struct {
// contains filtered or unexported fields
}
EachRule is a validation rule that validates elements in a map/slice/array using the specified list of rules.
func Each ¶
Each returns a validation rule that loops through an iterable (map, slice or array) and validates each value inside with the provided rules. An empty iterable is considered valid. Use the Required rule to make sure the iterable is not empty.
type ErrFieldNotFound ¶
type ErrFieldNotFound int
ErrFieldNotFound is the error that a field cannot be found in the struct.
func (ErrFieldNotFound) Error ¶
func (e ErrFieldNotFound) Error() string
Error returns the error string of ErrFieldNotFound.
type ErrFieldPointer ¶
type ErrFieldPointer int
ErrFieldPointer is the error that a field is not specified as a pointer.
func (ErrFieldPointer) Error ¶
func (e ErrFieldPointer) Error() string
Error returns the error string of ErrFieldPointer.
type Error ¶
type Error interface { Error() string Code() string Message() string SetMessage(string) Error Params() map[string]interface{} SetParams(map[string]interface{}) Error }
Error interface represents an validation error
type ErrorObject ¶
type ErrorObject struct {
// contains filtered or unexported fields
}
ErrorObject is the default validation error that implements the Error interface.
func (ErrorObject) AddParam ¶
func (e ErrorObject) AddParam(name string, value interface{}) Error
AddParam add parameter to the error's parameters.
func (ErrorObject) Message ¶
func (e ErrorObject) Message() string
Message return the error's message.
func (ErrorObject) Params ¶
func (e ErrorObject) Params() map[string]interface{}
Params returns the error's params.
func (ErrorObject) SetCode ¶
func (e ErrorObject) SetCode(code string) Error
SetCode set the error's translation code.
func (ErrorObject) SetMessage ¶
func (e ErrorObject) SetMessage(message string) Error
SetMessage set the error's message.
func (ErrorObject) SetParams ¶
func (e ErrorObject) SetParams(params map[string]interface{}) Error
SetParams set the error's params.
type Errors ¶
Errors represents the validation errors that are indexed by struct field names, map or slice keys. values are Error or Errors (for map, slice and array error value is Errors).
func (Errors) Filter ¶
Filter removes all nils from Errors and returns back the updated Errors as an error. If the length of Errors becomes 0, it will return nil.
func (Errors) MarshalJSON ¶
MarshalJSON converts the Errors into a valid JSON.
type FieldRules ¶
type FieldRules struct {
// contains filtered or unexported fields
}
FieldRules represents a rule set associated with a struct field.
func Field ¶
func Field(fieldPtr interface{}, rules ...Rule) *FieldRules
Field specifies a struct field and the corresponding validation rules. The struct field must be specified as a pointer to it.
type InRule ¶
type InRule struct {
// contains filtered or unexported fields
}
InRule is a validation rule that validates if a value can be found in the given list of values.
func In ¶
func In(values ...interface{}) InRule
In returns a validation rule that checks if a value can be found in the given list of values. reflect.DeepEqual() will be used to determine if two values are equal. For more details please refer to https://golang.org/pkg/reflect/#DeepEqual An empty value is considered valid. Use the Required rule to make sure a value is not empty.
func (InRule) ErrorObject ¶
ErrorObject sets the error struct for the rule.
type InternalError ¶
InternalError represents an error that should NOT be treated as a validation error.
func NewInternalError ¶
func NewInternalError(err error) InternalError
NewInternalError wraps a given error into an InternalError.
type KeyRules ¶
type KeyRules struct {
// contains filtered or unexported fields
}
KeyRules represents a rule set associated with a map key.
type LengthRule ¶
type LengthRule struct {
// contains filtered or unexported fields
}
LengthRule is a validation rule that checks if a value's length is within the specified range.
func Length ¶
func Length(min, max int) LengthRule
Length returns a validation rule that checks if a value's length is within the specified range. If max is 0, it means there is no upper bound for the length. This rule should only be used for validating strings, slices, maps, and arrays. An empty value is considered valid. Use the Required rule to make sure a value is not empty.
func RuneLength ¶
func RuneLength(min, max int) LengthRule
RuneLength returns a validation rule that checks if a string's rune length is within the specified range. If max is 0, it means there is no upper bound for the length. This rule should only be used for validating strings, slices, maps, and arrays. An empty value is considered valid. Use the Required rule to make sure a value is not empty. If the value being validated is not a string, the rule works the same as Length.
func (LengthRule) Error ¶
func (r LengthRule) Error(message string) LengthRule
Error sets the error message for the rule.
func (LengthRule) ErrorObject ¶
func (r LengthRule) ErrorObject(err Error) LengthRule
ErrorObject sets the error struct for the rule.
func (LengthRule) Validate ¶
func (r LengthRule) Validate(value interface{}) error
Validate checks if the given value is valid or not.
type MapRule ¶
type MapRule struct {
// contains filtered or unexported fields
}
MapRule represents a rule set associated with a map.
func Map ¶
Map returns a validation rule that checks the keys and values of a map. This rule should only be used for validating maps, or a validation error will be reported. Use Key() to specify map keys that need to be validated. Each Key() call specifies a single key which can be associated with multiple rules. For example,
validation.Map( validation.Key("Name", validation.Required), validation.Key("Value", validation.Required, validation.Length(5, 10)), )
A nil value is considered valid. Use the Required rule to make sure a map value is present.
func (MapRule) AllowExtraKeys ¶
AllowExtraKeys configures the rule to ignore extra keys.
type MatchRule ¶
type MatchRule struct {
// contains filtered or unexported fields
}
MatchRule is a validation rule that checks if a value matches the specified regular expression.
func Match ¶
Match returns a validation rule that checks if a value matches the specified regular expression. This rule should only be used for validating strings and byte slices, or a validation error will be reported. An empty value is considered valid. Use the Required rule to make sure a value is not empty.
func (MatchRule) ErrorObject ¶
ErrorObject sets the error struct for the rule.
type MultipleOfRule ¶
type MultipleOfRule struct {
// contains filtered or unexported fields
}
MultipleOfRule is a validation rule that checks if a value is a multiple of the "base" value.
func MultipleOf ¶
func MultipleOf(base interface{}) MultipleOfRule
MultipleOf returns a validation rule that checks if a value is a multiple of the "base" value. Note that "base" should be of integer type.
func (MultipleOfRule) Error ¶
func (r MultipleOfRule) Error(message string) MultipleOfRule
Error sets the error message for the rule.
func (MultipleOfRule) ErrorObject ¶
func (r MultipleOfRule) ErrorObject(err Error) MultipleOfRule
ErrorObject sets the error struct for the rule.
func (MultipleOfRule) Validate ¶
func (r MultipleOfRule) Validate(value interface{}) error
Validate checks if the value is a multiple of the "base" value.
type NotInRule ¶
type NotInRule struct {
// contains filtered or unexported fields
}
NotInRule is a validation rule that checks if a value is absent from the given list of values.
func NotIn ¶
func NotIn(values ...interface{}) NotInRule
NotIn returns a validation rule that checks if a value is absent from the given list of values. Note that the value being checked and the possible range of values must be of the same type. An empty value is considered valid. Use the Required rule to make sure a value is not empty.
func (NotInRule) ErrorObject ¶
ErrorObject sets the error struct for the rule.
type RequiredRule ¶
type RequiredRule struct {
// contains filtered or unexported fields
}
RequiredRule is a rule that checks if a value is not empty.
func (RequiredRule) Error ¶
func (r RequiredRule) Error(message string) RequiredRule
Error sets the error message for the rule.
func (RequiredRule) ErrorObject ¶
func (r RequiredRule) ErrorObject(err Error) RequiredRule
ErrorObject sets the error struct for the rule.
func (RequiredRule) Validate ¶
func (r RequiredRule) Validate(value interface{}) error
Validate checks if the given value is valid or not.
func (RequiredRule) When ¶
func (r RequiredRule) When(condition bool) RequiredRule
When sets the condition that determines if the validation should be performed.
type Rule ¶
type Rule interface { // Validate validates a value and returns a value if validation fails. Validate(value interface{}) error }
Rule represents a validation rule.
func WithContext ¶
func WithContext(f RuleWithContextFunc) Rule
WithContext wraps a RuleWithContextFunc into a context-aware Rule.
type RuleFunc ¶
type RuleFunc func(value interface{}) error
RuleFunc represents a validator function. You may wrap it as a Rule by calling By().
type RuleWithContext ¶
type RuleWithContext interface { // ValidateWithContext validates a value and returns a value if validation fails. ValidateWithContext(ctx context.Context, value interface{}) error }
RuleWithContext represents a context-aware validation rule.
type RuleWithContextFunc ¶
RuleWithContextFunc represents a validator function that is context-aware. You may wrap it as a Rule by calling WithContext().
type StringRule ¶
type StringRule struct {
// contains filtered or unexported fields
}
StringRule is a rule that checks a string variable using a specified stringValidator.
func NewStringRule ¶
func NewStringRule(validator stringValidator, message string) StringRule
NewStringRule creates a new validation rule using a function that takes a string value and returns a bool. The rule returned will use the function to check if a given string or byte slice is valid or not. An empty value is considered to be valid. Please use the Required rule to make sure a value is not empty.
func NewStringRuleWithError ¶
func NewStringRuleWithError(validator stringValidator, err Error) StringRule
NewStringRuleWithError creates a new validation rule using a function that takes a string value and returns a bool. The rule returned will use the function to check if a given string or byte slice is valid or not. An empty value is considered to be valid. Please use the Required rule to make sure a value is not empty.
func (StringRule) Error ¶
func (r StringRule) Error(message string) StringRule
Error sets the error message for the rule.
func (StringRule) ErrorObject ¶
func (r StringRule) ErrorObject(err Error) StringRule
ErrorObject sets the error struct for the rule.
func (StringRule) Validate ¶
func (r StringRule) Validate(value interface{}) error
Validate checks if the given value is valid or not.
type ThresholdRule ¶
type ThresholdRule struct {
// contains filtered or unexported fields
}
ThresholdRule is a validation rule that checks if a value satisfies the specified threshold requirement.
func Max ¶
func Max(max interface{}) ThresholdRule
Max returns a validation rule that checks if a value is less or equal than the specified value. By calling Exclusive, the rule will check if the value is strictly less than the specified value. Note that the value being checked and the threshold value must be of the same type. Only int, uint, float and time.Time types are supported. An empty value is considered valid. Please use the Required rule to make sure a value is not empty.
func Min ¶
func Min(min interface{}) ThresholdRule
Min returns a validation rule that checks if a value is greater or equal than the specified value. By calling Exclusive, the rule will check if the value is strictly greater than the specified value. Note that the value being checked and the threshold value must be of the same type. Only int, uint, float and time.Time types are supported. An empty value is considered valid. Please use the Required rule to make sure a value is not empty.
func (ThresholdRule) Error ¶
func (r ThresholdRule) Error(message string) ThresholdRule
Error sets the error message for the rule.
func (ThresholdRule) ErrorObject ¶
func (r ThresholdRule) ErrorObject(err Error) ThresholdRule
ErrorObject sets the error struct for the rule.
func (ThresholdRule) Exclusive ¶
func (r ThresholdRule) Exclusive() ThresholdRule
Exclusive sets the comparison to exclude the boundary value.
func (ThresholdRule) Validate ¶
func (r ThresholdRule) Validate(value interface{}) error
Validate checks if the given value is valid or not.
type Validatable ¶
type Validatable interface { // Validate validates the data and returns an error if validation fails. Validate() error }
Validatable is the interface indicating the type implementing it supports data validation.
type ValidatableWithContext ¶
type ValidatableWithContext interface { // ValidateWithContext validates the data with the given context and returns an error if validation fails. ValidateWithContext(ctx context.Context) error }
ValidatableWithContext is the interface indicating the type implementing it supports context-aware data validation.
type WhenRule ¶
type WhenRule struct {
// contains filtered or unexported fields
}
WhenRule is a validation rule that executes the given list of rules when the condition is true.
func When ¶
When returns a validation rule that executes the given list of rules when the condition is true.
func (WhenRule) Else ¶
Else returns a validation rule that executes the given list of rules when the condition is false.