New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
How to validate struct without struct tag? #853
Comments
I find a way to validate structure without struct tag, is this the current best way to validate no tag structure? This not my expect way to validate no tag structure. package main
import (
"fmt"
"testing"
"github.com/go-playground/validator/v10"
)
var (
v = validator.New()
withTag = WithTag{
RequestID: "",
Email: "email",
Phone: "123456",
Keywords: []string{""},
}
noTag = NoTag(withTag)
)
func main() {
v.RegisterStructValidation(noTagValidateFunc, NoTag{})
fmt.Println(v.Struct(withTag))
fmt.Println(v.Struct(noTag))
}
type WithTag struct {
RequestID string `validate:"required"`
Email string `validate:"omitempty,email"`
Phone string `validate:"omitempty,e164"`
Keywords []string `validate:"dive,required"`
}
type NoTag struct {
RequestID string
Email string
Phone string
Keywords []string
}
func noTagValidateFunc(sl validator.StructLevel) {
s := sl.Current().Interface().(NoTag)
v := sl.Validator()
if err := v.Var(s.RequestID, "required"); err != nil {
sl.ReportValidationErrors("RequiredID", "RequiredID", err.(validator.ValidationErrors))
}
if err := v.Var(s.Email, "omitempty,email"); err != nil {
sl.ReportValidationErrors("Email", "Email", err.(validator.ValidationErrors))
}
if err := v.Var(s.Phone, "omitempty,e164"); err != nil {
sl.ReportValidationErrors("Phone", "Phone", err.(validator.ValidationErrors))
}
if err := v.Var(s.Keywords, "dive,required"); err != nil {
sl.ReportValidationErrors("Keywords", "Keywords", err.(validator.ValidationErrors))
}
}
func BenchmarkWithTag(b *testing.B) {
for i := 0; i < b.N; i++ {
_ = v.Struct(withTag)
}
}
func BenchmarkNoTag(b *testing.B) {
for i := 0; i < b.N; i++ {
_ = v.Struct(noTag)
}
} And benchmark result: $ go test -bench=. -benchmem .
goos: darwin
goarch: amd64
pkg: github.com/chenyanchen/test/validator
cpu: Intel(R) Core(TM) i5-1038NG7 CPU @ 2.00GHz
BenchmarkWithTag-8 515580 2031 ns/op 998 B/op 17 allocs/op
BenchmarkNoTag-8 6123906 200.5 ns/op 80 B/op 1 allocs/op
PASS
ok github.com/chenyanchen/test/validator 3.147s |
Currently, there is nothing that would do this, except the painful way of using the Maybe it's worth exploring a path, where we can pass in validation rules as an argument to the validation function as we do with map validation https://pkg.go.dev/github.com/go-playground/validator/v10#Validate.ValidateMap Would look something like func (v *Validate) StructWithRules(s interface{}, rules map[string]interface{}) error |
I suggest // rules is map[FieldName]Tag
func (v *Validate) RegisterStructValidationInMap(rules map[string]string, types ...interface{}) |
The way I would approach this problem would be to use two different structs for the different purposes. I would use the structs generated by protoc for my gRPC and Protobuf use cases (receiving data over the wire), map the data from the Protobuf struct to a new struct I create with the validation tags, perform the validation on this new struct with the data filled in, and use the result of that validation to decide what to do with the data in the Protobuf struct received over the wire. |
I archieved this function,PR:#934 |
^ boiler plate approach, not recommended |
Package version v10:
import "github.com/go-playground/validator/v10"
Issue, Question or Enhancement:
I made some gRPC services with protobuf, the generated files has no struct tags. How to validate a struct without struct tags?
Maybe gogo/protobuf can add some struct tags into the generation files, but this is no matter to use a new package for the complex method.
I find the same problem #722 not same pain spot and closed.
There is some simply method to solove this problem?
Code sample, to showcase or reproduce:
.proto
fileGenerated structure:
I want validate this structure equal this:
In the proto generated files, there is no tags, so I expect a method like
RegisterStructMap
, themap[string]string
ismap[FieldName]tag
.The text was updated successfully, but these errors were encountered: