Package govalidator
Validate golang request data with simple rules. Highly inspired by Laravel's request validation.
Installation
Install the package using
$ go get github.com/thedevsaddam/govalidator
// or
$ go get gopkg.in/thedevsaddam/govalidator.v1
Usage
To use the package import it in your *.go code
import "github.com/thedevsaddam/govalidator"
// or
import "gopkg.in/thedevsaddam/govalidator.v1"
Example
Validate form-data, x-www-form-urlencoded and query params
package main
import (
"encoding/json"
"fmt"
"net/http"
"github.com/thedevsaddam/govalidator"
)
func handler(w http.ResponseWriter, r *http.Request) {
rules := govalidator.MapData{
"username": []string{"required", "between:3,8"},
"email": []string{"required", "min:4", "max:20", "email"},
"web": []string{"url"},
"phone": []string{"digits:11"},
"agree": []string{"bool"},
"dob": []string{"date"},
}
messages := govalidator.MapData{
"username": []string{"required:আপনাকে অবশ্যই ইউজারনেম দিতে হবে", "between:ইউজারনেম অবশ্যই ৩-৮ অক্ষর হতে হবে"},
"phone": []string{"digits:ফোন নাম্বার অবশ্যই ১১ নম্বারের হতে হবে"},
}
opts := govalidator.Options{
Request: r, // request object
Rules: rules, // rules map
Messages: messages, // custom message map (Optional)
RequiredDefault: true, // all the field to be pass the rules
}
v := govalidator.New(opts)
e := v.Validate()
err := map[string]interface{}{"validationError": e}
w.Header().Set("Content-type", "applciation/json")
json.NewEncoder(w).Encode(err)
}
func main() {
http.HandleFunc("/", handler)
fmt.Println("Listening on port: 9000")
http.ListenAndServe(":9000", nil)
}
Send request to the server using curl or postman: curl GET "http://localhost:9000?web=&phone=&zip=&dob=&agree="
Response
{
"validationError": {
"agree": [
"The agree may only contain boolean value, string or int 0, 1"
],
"dob": [
"The dob field must be a valid date format. e.g: yyyy-mm-dd, yyyy/mm/dd etc"
],
"email": [
"The email field is required",
"The email field must be a valid email address"
],
"phone": [
"ফোন নাম্বার অবশ্যই ১১ নম্বারের হতে হবে"
],
"username": [
"আপনাকে অবশ্যই ইউজারনেম দিতে হবে",
"ইউজারনেম অবশ্যই ৩-৮ অক্ষর হতে হবে"
],
"web": [
"The web field format is invalid"
]
}
}
Validation Rules
alphaThe field under validation must be entirely alphabetic characters.alpha_dashThe field under validation may have alpha-numeric characters, as well as dashes and underscores.alpha_numThe field under validation must be entirely alpha-numeric characters.between:numeric,numericThe field under validation check the length of characters/ length of array, slice, map/ range between two integer or float number etc.numericThe field under validation must be entirely numeric characters.numeric_between:numeric,numericThe field under validation must be a numeric value between the range.
e.g:numeric_between:18,65may contains numeric value like35,55. You can also pass float value to checkboolThe field under validation must be able to be cast as a boolean. Accepted input aretrue, false, 1, 0, "1" and "0".credit_cardThe field under validation must have a valid credit card number. Accepted cards areVisa, MasterCard, American Express, Diners Club, Discover and JCB cardcoordinateThe field under validation must have a value of valid coordinate.css_colorThe field under validation must have a value of valid CSS color. Accepted colors arehex, rgb, rgba, hsl, hslalike#909, #00aaff, rgb(255,122,122)dateThe field under validation must have a valid date of format yyyy-mm-dd or yyyy/mm/dd.date:dd-mm-yyyyThe field under validation must have a valid date of format dd-mm-yyyy.digits:intThe field under validation must be numeric and must have an exact length of value.digits_between:int,intThe field under validation must be numeric and must have length between the range.
e.g:digits_between:3,5may contains digits like2323,12435in:foo,barThe field under validation must have one of the values. e.g:in:admin,manager,usermust contain the values (admin or manager or user)not_in:foo,barThe field under validation must have one value except foo,bar. e.g:not_in:admin,manager,usermust not contain the values (admin or manager or user)emailThe field under validation must have a valid email.floatThe field under validation must have a valid float number.max:numericThe field under validation must have a min length of characters for string, items length for slice/map, value for integer or float.
e.g:min:3may contains characters minimum length of 3 like"john", "jane", "jane321"but not"mr", "xy"max:numericThe field under validation must have a max length of characters for string, items length for slice/map, value for integer or float.
e.g:max:6may contains characters maximum length of 6 like"john doe", "jane doe"but not"john", "jane"len:numericThe field under validation must have an exact length of characters, exact integer or float value, exact size of map/slice.
e.g:len:4may contains characters exact length of 4 likeFood, Mood, GoodipThe field under validation must be a valid IP address.ip_v4The field under validation must be a valid IP V4 address.ip_v6The field under validation must be a valid IP V6 address.jsonThe field under validation must be a valid JSON string.latThe field under validation must be a valid latitude.lonThe field under validation must be a valid longitude.regex:regurlar expressionThe field under validation validate against the regex. e.g:regex:^[a-zA-Z]+$validate the letters.requiredThe field under validation must be present in the input data and not empty. A field is considered "empty" if one of the following conditions are true: 1) The value is null. 2)The value is an empty string. 3) Zero length of map, slice. 4) Zero value for integer or floatsize:integerThe field under validation validate a file size only in form-data (see example)ext:jpg,pngThe field under validation validate a file extension (see example)mime:image/jpg,image/pngThe field under validation validate a file mime type (see example)urlThe field under validation must be a valid URL.uuidThe field under validation must be a valid UUID.uuid_v3The field under validation must be a valid UUID V3.uuid_v4The field under validation must be a valid UUID V4.uuid_v5The field under validation must be a valid UUID V5.
Add Custom Rules
func init() {
// simple example
govalidator.AddCustomRule("must_john", func(field string, rule string, message string, value interface{}) error {
val := value.(string)
if val != "john" || val != "John" {
return fmt.Errorf("The %s field must be John or john", field)
}
return nil
})
// custom rules to take fixed length word.
// e.g: word:5 will throw error if the field does not contain exact 5 word
govalidator.AddCustomRule("word", func(field string, rule string, message string, value interface{}) error {
valSlice := strings.Fields(value.(string))
l, _ := strconv.Atoi(strings.TrimPrefix(rule, "word:")) //handle other error
if len(valSlice) != l {
return fmt.Errorf("The %s field must be %d word", field, l)
}
return nil
})
}
Note: Array, map, slice can be validated by adding custom rules.
Custom Message/ Localization
If you need to translate validation message you can pass messages as options.
messages := govalidator.MapData{
"username": []string{"required:You must provide username", "between:The username field must be between 3 to 8 chars"},
"zip": []string{"numeric:Please provide zip field as numeric"},
}
opts := govalidator.Options{
Messages: messages,
}
Validate File
For multipart/form-data validation, use file: prefix to field name which contains the file. If use custom message then also use the file: prefix to Messages MapData key.
package main
import (
"encoding/json"
"fmt"
"net/http"
"github.com/thedevsaddam/govalidator"
)
func handler(w http.ResponseWriter, r *http.Request) {
rules := govalidator.MapData{
"file:photo": []string{"ext:jpg,png", "size:10000", "mime:jpg,png", "required"},
}
messages := govalidator.MapData{
"file:photo": []string{"ext:Only jpg/png is allowed", "required:Photo is required"},
}
opts := govalidator.Options{
Request: r, // request object
Rules: rules, // rules map,
Messages: messages,
}
v := govalidator.New(opts)
e := v.Validate()
err := map[string]interface{}{"validationError": e}
w.Header().Set("Content-type", "applciation/json")
json.NewEncoder(w).Encode(err)
}
func main() {
http.HandleFunc("/", handler)
fmt.Println("Listening on port: 9000")
http.ListenAndServe(":9000", nil)
}
Resposne
{
"validationError": {
"photo": [
"Photo is required"
]
}
}
or
{
"validationError": {
"photo": [
"Only jpg/png is allowed",
"The photo field size is can not be greater than 10000 bytes",
"The photo field file mime text/plain is invalid"
]
}
}
Hope you'll like the package 
