ini icon indicating copy to clipboard operation
ini copied to clipboard

support validation for each field

Open bruceauyeung opened this issue 8 years ago • 13 comments

some mechanism like this:

type Person struct {
    Name string `validateExp:^\d+$` // Go Regexp here
}
type Entity struct {
    Name string `validateFunc:validateEntityName` // funcation name here
}
func validateEntityName(name string)(bool, error){
// validation codes here
}

then go-ini will do validation works automatically.

bruceauyeung avatar Jun 04 '17 05:06 bruceauyeung

Hi, thanks for the idea!

But I would recommend user makes the struct implements an interface and do customized validation in the user-defined method.

unknwon avatar Jun 05 '17 02:06 unknwon

@Unknwon

  1. it's better to separate validation logics from user's business logics, putting validation logics in user-defined method which implements an interface means interface methods are polluted. besides usually business logics may be called multiple times for one instance of struct, but validation logics shouldn't be.

  2. validation should be bidirectional because go-ini supports read from and save to ini files. if user have plenty of instances of a struct to be serialized, user has to call those validation methods manually over and over again. this will make code really nasty. built in validation mechanism will make life easier.

  3. big structs and nested structs means lots of validation methods to be called manually, nasty work!

  4. putting validation logics directly/indrectly in struct tags like i sugguested can let user quickly know/remind user what limitations/restrictions/rules are applied to that field, this is stronger binding than others.

bruceauyeung avatar Jun 05 '17 12:06 bruceauyeung

No, what I meant is user implements interface with methods, for example MapVaildation and RefecltValiddation. You write validation logic but you don't call them.

unknwon avatar Jun 05 '17 16:06 unknwon

is MapValidation named after field type or name ?

bruceauyeung avatar Jun 06 '17 01:06 bruceauyeung

It will look like (s *Struct) MapValidation(filedName string, value interface{}) error.

unknwon avatar Jun 06 '17 05:06 unknwon

  1. mechanism i suggested seems to be more intuitive, more declarative and easier to read than MapValidation. When someone look at this struct definition, he/she can absolutely guess/know what validation logics for the field is ,even when he/she don't know go-ini very well.
  2. mechanism i suggested seems to be more general. Any other golang libs such as json, yaml can also utilize these tags. they can just ignore of course.
  3. we can also validate a field with more than one validation funcs but still have good readability, like :
type Entity struct {
    Name string `validateFuncs:fnAlphaNumericOnly,validateEntityName`
}

bruceauyeung avatar Jun 06 '17 07:06 bruceauyeung

OK, I can accept:

type Person struct {
    Name string `regexp:"^\d+$"` // Go Regexp here
}

But no funcs, it is not a good idea from my perspective.

unknwon avatar Jun 06 '17 07:06 unknwon

can we both have regexp tag and MapValidation ? If let me choose between regexp tag and MapValidation, i choose MapValidation because lack of functions make user hardly to reuse codes/regexp.

bruceauyeung avatar Jun 06 '17 08:06 bruceauyeung

If you already have MapValidation, there is no need to add tags, that's more confusing.

unknwon avatar Jun 06 '17 08:06 unknwon

ok, vote for MapValidation and no regexp tag ps: can we build in some general validation functions ( isAlphanumeric, IsDigit, etc )?

bruceauyeung avatar Jun 06 '17 08:06 bruceauyeung

Maybe we should just add similar thing as https://go-macaron.com/docs/middlewares/binding#validate

unknwon avatar Jun 06 '17 08:06 unknwon

looks like validate tag ( for builtin validation funcs ) and MapValidation( for custom validation) works together

bruceauyeung avatar Jun 06 '17 09:06 bruceauyeung

Basically, yes.

unknwon avatar Jun 06 '17 17:06 unknwon