Home > Software design >  Golang create custom validator that executes method of an interface
Golang create custom validator that executes method of an interface

Time:07-14

I am trying to create my own validator for gin, but I want it to be "generic", so let's say, I want to have an interface IsValid

type IsValid interface {
    IsValid() bool
}

, and make some structs to have binding:"IsValid" in some fields that implement that interface.

But I don't know how to write my custom validator to get the field, cast it to the IsValid interface, and then execute the isValid method.

I am using the go-playground validator package: https://github.com/go-playground/validator

if v, ok := binding.Validator.Engine().(*validator.Validate); ok {
    // registering validation for isValid
    v.RegisterValidation("isValid", func(fl validator.FieldLevel) bool {
        isValidField := // TODO do something to cast it to that interface
        return isValidField.IsValid()
    })
}

CodePudding user response:

The FieldLevel type has this method:

// returns current field for validation
Field() reflect.Value

reflect.Value has this method:

func (v Value) Interface() (i any)

Interface returns v's current value as an interface{}. It is equivalent to:

var i interface{} = (v's underlying value)

It panics if the Value was obtained by accessing unexported struct fields.

You can use a type assertion to utilize an interface{} / any value as a more specific interface like this:

var i interface{} = something
var x = i.(MyInterface)

This will panic if the value i doesn't implement MyInterface. To check for that case, the alternate form can be used:

var x, ok = i.(MyInterface)
if ok {
    // use x
} else {
    // type conversion failed
}

Putting it together, your code would be something like this:

isValidField, ok := fl.Field().Interface().(IsValid)
  • Related