go-validator / validator Goto Github PK
View Code? Open in Web Editor NEWPackage validator implements struct field validations
License: Apache License 2.0
Package validator implements struct field validations
License: Apache License 2.0
validate:"regexp=^[a-z0-9]{1,200}$"
returns unknown tag
error. If I remove {1,200}
it works though.
implement a method that format a json
response, example:
type NewUserRequest struct {
Age int `validate:"min=21"`
}
nur := NewUserRequest{Username: "something", Age: 20}
if err := validator.Validate(nur); errs != nil {
http.Error(w, err.HttpResponse(), http.StatusBadRequest)
}
// or
if err := validator.Validate(nur); errs != nil {
err.HttpResponse(w)
return
}
The response format could be:
{
"message": "invalid length",
"detail": "invalid length for field age - min=21",
"code": 401
}
In api web contexts sometimes we might want to directly serialize the errors out to a front-end.
Unfortunately the errors generated by this package are not friendly to the json package since error is not something the json package understands how to serialize.
http://play.golang.org/p/kYNalRk1CY
However by introducing a small proxy type for error that implements MarshalText we can have the json emitted no problem.
http://play.golang.org/p/-AhEaXMP-c
This change seems quite reasonable to cover a common use case in the web world without affecting backwards compatibility.
Currently, embedded struct fields are not validated, if the struct type itself is not exported.
For example, this code validates field A:
type Base struct {
A string `validate:"min=1"`
}
type Sub struct {
Base
}
However, this code does not, since base
is an unexported type (then field name is base
so is skipped:
type base struct {
A string `validate:"min=1"`
}
type Sub struct {
base
}
Simply changing this code leads to an error, because we can't actually access the field value directly, since base
is itself unexported (see https://github.com/go-validator/validator/blob/v2/validator.go#L218)
Instead, we need to take the type itself, and walk those fields in the struct.
I took a stab at a proof of concept here: https://github.com/rgalanakis/validator/commits/v2
I had to do a bit of refactoring so the validations could be called recursively. I don't love it (passing around m
as a mutable argument) but I wanted to avoid too many large changes so you could see the diff.
That example does not work with embedded pointer fields- it will panic (ie, type Sub struct { *base }
). I have done it before, so I know it's possible, but I need to dig a bit more (I think we need to access fields by name rather than index).
thanks
I have tried multiple times, but when validator goes on struct, it can never raise error for empty string.
I tried to duplicate sample code, and the validator still cannot examine empty string.
Hi, I am having some trouble when using validation package. It's return error
Handler crashed with error interface conversion: interface is nil, not string
it's occurred because some client forgot or maybe test the API validation with skipped one or more required parameters and I want this handled by validator package.
This is the details. may you help me ?. Thanks anyway
type ParamRequest struct {
PhoneNumber string `validate:"nonzero"`
ItemCode string `validate:"nonzero"`
}
func (c *TopupAlloperatorApiController) Post() {
interf := make(map[string]interface{})
json.Unmarshal(c.Ctx.Input.RequestBody, &interf)
ve := ParamRequest{
PhoneNumber: interf["PhoneNumber"].(string),
ItemCode: interf["ItemCode"].(string),
}
}
When I use validate in an anonymous embedded struct, then it is not validated on calling the parent struct validate function.
Is this expected?
Hello,
Is there any built-in omitempty
definition?
There is a problem if a comma is a part of a the regex string.
An example here:
type Company struct {
Name string `validate:"regexp=^[a-zA-Z]{1,100}$"`
}
This gives the error "Name: unknown tag" while doing validator.Validate(C)
, C here is of type struct, of course.
The (line) in the file validator.go splits the tag.
Escaping the commas and making modifications to the validator.go code would be the solution I think,
Any thoughts on how to proceed?
regexp validator not working using lookaheads.
using the following struct i cannot get the validator to work
type pwd struct {
Password string `validate:"regexp=^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[.!@#\\$%\\^&\\*])(?=.{8\\,})"`
}
Expected result: password must have 1 of each lower, upper numeral and special , and be atleast 8 characters long
Actual result: either no validation occurs or Password (bad parameter)
is returned
Thanks
Let's imagine I have a payload to validate like this:
type Person struct{
Name string `validate:"nonzero" json:"name"`
Age int `validate:"min=18" json:"age"`
}
If I receive a JSON payload like this:
{"name":"John","age":10}
I would like to get an error telling me that age
is supposed to be at least 18. But in the ErrorMap the key is Age
And once I have the Age
it's kind of complicated to parse my struct again in order to get the json tag again.
Do you guys think we could configure the validator to parse and use the json tag in the payload?
I suppose this could be very useful in a lot of projects - among others like credit-card, zip codes and so on.
I understand that the user can easily write that validations on his/ her own but this means its done repeatedly in a lot of projects.
Example pattern in YAML validation:
Listen string `yaml:"Listen,omitempty" validate:"regexp=^(([0-9]+[.][0-9]+[.][0-9]+[.][0-9]+)?[:][0-9]\{1,6\})$"`
temporary solution in my configuration:
Listen string `yaml:"Listen,omitempty" validate:"regexp=^(([0-9]+[.][0-9]+[.][0-9]+[.][0-9]+)?[:][0-9]+)$"`
I'm using pointer to strings in my struct to make it easier to deal with databases and inserting a NULL value instead of empty string "" into the table.
type User struct {
Address1 *string `validate:"max=100"`
}
When Address1=nil the validator will fail with unsupported type.
My question, is there a way to chain validators or only apply validators if the value pointer is not nil?
If no, does this mean I have to reimplement a custom validator to check it myself?
Validate()
is defined as a function that returns an error
But when everything goes fine, it actually returns an ErrorMap
map, but it has to be casted otherwise an error appears when we want to manipulate the errs map (Register()
is just a function that registers all my custom validators) :
IMO it is a bad conception and this should be modified. But the most annoying aspect is that your README is wrong...
当我写了一个密码验证
Password string `json:"password" validate:"regexp=^[a-zA-Z0-9]{8,15}$"`
表明了这个参数不会必传, 然后在请求传空或者不传的情况下, 调用validator.Validate就会报错, 建议加一个判空操作, 当参数不是必传且为空时, 可以不走正则校验
Validation is extremely slow. I was validating every struct that I parsed from JSON. The JSON would contain long strings of base64-encoded binary data, up to 16 KB. Disabling validation increased throughput 20-fold, so this was a major bottleneck. Most struct types did not even have 'validate' annotations on them, yet still a lot of time was spent "validating".
If I got a struct like this
type NewUserRequest struct {
Username string `db:'user_name' validate:"min=3,max=40,regexp=^[a-zA-Z]$"`
}
The validation for user name will always be correct, but if I change it to:
type NewUserRequest struct {
Username string `validate:"min=3,max=40,regexp=^[a-zA-Z]$" db:'user_name'`
}
It will validate correctly.
Not sure what I am doing wrong but I cannot get regexp validation working.
Consider this type:
type EmailAddress struct {
EmailAddress string `json:"emailaddress" validate:"regexp=^[a-z0-9._%+\-]+@[a-z0-9.\-]+\.[a-z]{2,4}$"`
Label string `json:"label" validate:"regexp=^[a-zA-Z\d\-_\s]{2,50}$"`
}
I would expect it to give an error when I supply it with this:
email := EmailAddress{
EmailAddress: "!@#$%$^#&^**(&", // just random invalid characters to be sure it triggers an error in the validation
Label: "!@#$%$}",
}
log.Debug(validator.Validate(email))
Instead what I get is nil. min/max validations work fine, but regexp doesn't seem to work at all. Am I doing something wrong or is there something else I'm missing?
I'm using the v2 branch.
On your example
if errs := validator.Validate(form); errs != nil {
You say it returns an array of errors but it currently returns a single error... is this intended or I am missing something?
Also is it possible to set a custom field name for the returned error?
HI,
If i use the example for this package, the program exits with Valid. Also when i change Username to 1 character the program will exit with Valid while i would expect Invalid.
package main
import (
"gopkg.in/validator.v1"
"fmt"
)
type NewUserRequest struct {
Username string `validator:"min=3,max=40,regexp=^[a-zA-Z]$"`
Name string `validator:"nonzero"`
Age int `validator:"min=21"`
Password string `validator:"min=8"`
}
func main() {
nur := NewUserRequest{Username: "something", Age: 20}
if valid, _ := validator.Validate(nur); !valid {
fmt.Println("Invalid")
} else {
fmt.Println("Valid")
}
}
The Go versions i used to test this, downgrading Go to 1.2.2 didn't help as well.
go version go1.2.2 darwin/amd64
go version go1.3 darwin/amd64
I see this is controversy but I give it a try:
type ValidationError struct {
Errors map[string][]error
}
// Returns first error.
func (err ValidationError) Error() {
for k, errs := range err.Errors {
return k + " value had " + errs[0].Error()
}
}
Hey,
Currently, any validate tag on a string alias type would fail with ErrUnsupported
:
type emailType string
type ValidateExample struct {
Email emailType `validate:"regexp=^[0-9a-z]+@[0-9a-z]+(\\.[0-9a-z]+)+$"`
}
Thanks.
type User struct { Name string
validate:"regexp=[A-Z]{1,3}"}
Error: Name: unknown tag
func (mv *Validator) copy() *Validator {
return &Validator{
tagName: mv.tagName,
validationFuncs: mv.validationFuncs,
}
}
validationFuncs is a map, newValidator.validationFuncs will share same memory with oldValidator.validationFuncs.
Refer To Go: copying all elements of a map into another
Hello Roberto!
Have you thought of using a different error struct for internal errors (e.g. ErrUnsupported
, ErrBadParameter
, ErrUnknownTag
)?
One use case where this may be handy is to decide if I send a http.StatusInternalServerError
or a http.StatusBadRequest
or maybe even do a panic because of wrong validation settings.
Would be great if there's an easy way to customize error messages.
In the different validators, the functions panic if the type is unknown, I think it would be more go-compliant to return an error. According to me, if the type is not supported, it should be simply a validation error.
What do you thing of that?
I haven't tried to dissect the problem, but I'm using go 1.4 and (I think) following the instructions.
type Query struct {
Q string `validate:"min=1,max=10,regexp=^[a-zA-Z]$"`
}
edit:
I'll leave this open because it may be a typo in the README, but this is my sucky understanding of regular expressions at fault: ^[a-zA-Z]+$
is the correct usage.
Hi,
why is false
a zero value for a bool pointer? I'm using a pointer on purpose so I can distinguish between ommited struct fields and set fields in my HTTP PATCH route.
When passing false
I'm getting: "Enabled: zero value".
Any idea?
The docs explain the advantage of using validatins with tags to avoid large amounts of code.
In code it is often necessary to validate that a given value is valid before using it for something. A typical example might be something like this.
if age < 18 { return error.New("age cannot be under 18") }This is a simple enough example, but it can get significantly more complex, especially when dealing with structs.
l := len(strings.Trim(s.Username)) if l < 3 || l > 40 || !regexp.MatchString("^[a-zA-Z]$", s.Username) || s.Age < 18 || s.Password { return errors.New("Invalid request") }
But like in the first code example I'm able to return more specific details about the erros that I want to return in the response of my restful api. In the second example, the response doesn't contain any hints.
Is there a way to combine both approaches' advantages?
Hey,
a validation such as below won't work, seems like the nonnil
func does not handle functions right.
type Foo {
Func func() `validate:"nonnil"`
}
The json
and bson
package omit fields with -
as value. I think we should add support for this to the validator package too.
Use case where it would have benefits:
type Customer struct {
Id bson.ObjectId `bson:"_id"`
Name string `validate:"nonzero"`
}
type Order struct {
Id bson.ObjectId `bson:"_id"`
// Reference to customer
CustomerId *mgo.DBRef
// Field to fetch customer reference
Customer Customer
}
func main() {
if ok, err := validator.Validate(Order{}); !ok {
log.Fatal(err)
}
}
The above Order
struct allows it to easily fetch the reference to Customer
onto the Customer
field. However if I now validate the struct it will return an error because Customer.Name
does not pass nonzero
constraint. However in this case there is no need to extra validate Customer
but validator gives me no way to omit validation for Customer
.
Validators for the various AWS object naming requirements should be added. Not being able to use regex makes it hard to add these on the fly.
The docs say that A int
validate:"max=0,nonzero"` will never be valid.
But wouldn't -1
be a valid value?
Hey,
Just wondering if there would be any interest in returning a newline or space seperated string containing all the errors in the map rather than just the first one range hits?
This is very simple validator and needs improvements for building modern web-application.
It must have the following validators:
version: gopkg.in/validator.v2 v2.0.0-20180514200540-135c24b11c19
expected behaviour: documentation for nonzero
validation for pointers states that
validates that the value is not zero. The appropriate zero value is given by the Go spec (e.g. for int it's 0, for string it's "", for pointers is nil, etc.)"
observed behavior: in contrast to what is stated by documentation, pointer fields tagged as validator:"nonzero"
with non-nil values are regarded as invalid when they reference a value that is zero. (e.g. non-nil pointer to false bool is regarded as invalid, similarly non-nil pointer to zero int).
related: #51
suggested improvement: update documentation to clarify existing behaviour and mention workaround described in #51 (comment) for people who only want to validate that the pointer is nonzero.
My struct looks like this:
type Bla struct {
ID sql.NullInt64 `validate:"customValidator"`
}
But it will never be validated.
It seems that go-validator looks in each element within the sql.NullInt struct for validation tags, but not on the struct itself.
Any hints besides using a *sql.NullInt64?
It took me time to figure out that this does not work:
if valid, err := validator.Validate(mystruct); !valid {
fmt.Println("Error")
}
I had to look at the code after 1 hour to realize it should be:
if err := validator.Validate(mystruct); err != nil {
fmt.Println("Error...")
}
The regexp
validation is currently only allowed on strings, but a common use case the need to validate all strings in a slice.
Right now trying to validate time.Time with nonzero causes a panic:
panic: reflect.Value.Interface: cannot return value obtained from unexported field or method [recovered]
panic: reflect.Value.Interface: cannot return value obtained from unexported field or method
goroutine 23 [running]:
runtime.panic(0x251c20, 0xc2080015f0)
/usr/local/Cellar/go/1.3/libexec/src/pkg/runtime/panic.c:279 +0xf5
testing.func·006()
/usr/local/Cellar/go/1.3/libexec/src/pkg/testing/testing.go:416 +0x176
runtime.panic(0x251c20, 0xc2080015f0)
/usr/local/Cellar/go/1.3/libexec/src/pkg/runtime/panic.c:248 +0x18d
reflect.valueInterface(0x2f5280, 0x4d42e0, 0x0, 0x197, 0x1, 0x0, 0x0)
/usr/local/Cellar/go/1.3/libexec/src/pkg/reflect/value.go:1081 +0x10c
reflect.Value.Interface(0x2f5280, 0x4d42e0, 0x0, 0x197, 0x0, 0x0)
/usr/local/Cellar/go/1.3/libexec/src/pkg/reflect/value.go:1070 +0x5c
gopkg.in/validator%2ev2.(*Validator).Validate(0xc208042040, 0x318d00, 0xc2080056a8, 0x0, 0x0)
/Users/lcurry/.go/src/gopkg.in/validator.v2/validator.go:233 +0x823
gopkg.in/validator%2ev2.(*Validator).Validate(0xc208042040, 0x2faea0, 0xc208005680, 0x0, 0x0)
/Users/lcurry/.go/src/gopkg.in/validator.v2/validator.go:233 +0x858
gopkg.in/validator%2ev2.(*Validator).Validate(0xc208042040, 0x3100e0, 0xc2080736c0, 0x0, 0x0)
/Users/lcurry/.go/src/gopkg.in/validator.v2/validator.go:233 +0x858
gopkg.in/validator%2ev2.(*Validator).Validate(0xc208042040, 0x306a60, 0xc208073180, 0x0, 0x0)
/Users/lcurry/.go/src/gopkg.in/validator.v2/validator.go:202 +0x20d
gopkg.in/validator%2ev2.Validate(0x306a60, 0xc208073180, 0x0, 0x0)
/Users/lcurry/.go/src/gopkg.in/validator.v2/validator.go:192 +0x50
[...]
Also, this won't fix the error above, but reflect.Zero might be helpful to detect zero values. We could rewrite nonzero to be something like:
// nonzero tests whether a variable value non-zero
// as defined by the golang spec.
func nonzero(v interface{}, param string) error {
zero := reflect.Zero(reflect.TypeOf(v)).Interface()
if v == zero {
return ErrZeroValue
}
return nil
}
I want to add some custom validator rule base on your validator
How can I do to add custom rule ?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.