3 ms·
I've attacked this from a few angles myself—previously using reflection and struct tags - `min:"2", max:"50"` - but found it fairly inelegant (although practica
by elithrar 12y ago
I've attacked this from a few angles myself—previously using reflection and struct tags - `min:"2", max:"50"` - but found it fairly inelegant (although practical). I wrote some good tests around it, that's for sure.
Now I'm a fan of https://github.com/katco-/vala https://github.com/katco-/vala which has a nice API for doing this for you. I've ripped out one of the examples from the README (which I think illustrates it well), but you could also wrap this in a method that you call on the instance of the struct you get back from (i.e.) gorilla/schema:
func ClearValidation(a, b, c MyType) (err error) {
err = BeginValidation().Validate(
IsNotNil(a, "a"),
IsNotNil(b, "b"),
IsNotNil(c, "c"),
).CheckAndPanic().Validate( // Panic will occur here if a, b, or c are nil.
HasLen(a.Items, 50, "a.Items"),
GreaterThan(b.UserCount, 0, "b.UserCount"),
Equals(c.Name, "Vala", "c.name"),
Not(Equals(c.FriendlyName, "Foo", "c.FriendlyName")),
).Check()
if err != nil {
return err
}
// ...
}
Note that for any reasonable amount of validation w/ structs (i.e. not nil, ranging over it automatically, etc) you will need reflection. There are no ifs or buts about that. But the whole 'reflection is slow' mantra is premature optimisation: if you need reflection, you need it. Your template rendering uses reflection, your database connection introduces latency, etc - all of that dwarfs any cost associated with validating a struct or two.
- aaron-lebo 12y agoThanks for your response. It is good to hear from someone who has wrestled with the issue.