Golang parameter validation: drawbacks of go-playground/validator and its replacement checker
Parameter validation in Golang, go-playground/validator is mostly used (gin framework uses valudator v8/v9).
However, the main drawback of go-playground/validator is that writing validation logic into tags of Golang struct, which is invasive and hard to read.
To solve the drawback, I wrote checker, as a replacement of go-playground/validator. Checker can used for struct or non-sturct validation in Golang.
Customized validation Rule
Using validator
Customized validator of playground/validator is a bit complicated, below is the official example:
Using checker
Using checker, users don’t need to write tags inside struct, and the validation logic is more readable. More examples can be foune here.
Customized error message
Using validator
Custiomizing error message in validator
is not easy, it needs to use translator.
Below is the official example:
Using checker
checker
can customized error prompt when adding rule.
func (c *ruleChecker) Add(rule Rule, prompt string) {
c.rules = append(c.rules, rule)
c.prompts = append(c.prompts, prompt)
}
For example, prompt is user-defined message returned when parameter cannot pass rule.
ch.Add(rule, "value is not awesome")
isValid, prompt, errMsg := ch.Check(s)
Easy for checker, hard for validator
The main drawback of validator
is, validation rule is attached to fields in struct via tag, which is intrusive, and hard to read the validation logic.
validation sturct of third party
package thrid_partytype Param struct{
Age `validate:"min=18,max=80"`
}
In user’s package, try to change min to 20, validator
can not change the validation rule, as we cannot change the struct layout outside our packages.
package mainfunc validate(p thrid_party.Param)(isValid bool){
....
}
If use checker
, the rule is simpler:
rule := checker.NewRangeRuleInt("Age", 20, 80)
checker.Add(rule, "invlaid age")
Because validation rule of checker
is decoupled from struct, which makes changes validation rule easy.
validate the length of linkedlist
The example is here.
type list struct {
Name *string
Next *list `validate:"nonzero"`
}
To validate the length of linkedlist, requiring the first node’s Next
cannot be nil. validator
cannot do this, for the same tag is attached to the same field.
If use checker
,
name := "list"
node1 := list{Name: &name, Next: nil}
lists := list{Name: &name, Next: &node1} listChecker := checker.NewChecker()
nameRule := checker.NewLengthRule("Next.Name", 1, 20)
listChecker.Add(nameRule, "invalid info name")
Length can be defined by Next.Name