LoginSignup
1
0

More than 3 years have passed since last update.

go-playground / validatorライブラリアップデート作業メモv8 -> v10

Posted at

前書き

今後同じ作業をする方と自分の振り返りのため、メモを残します。

goバージョン go-playground / validatorバージョン
v1.15.3 v10.4.1

TagName

v8のvalidatorはデフォルトのTagNameを指定してありません。
毎回validator初期化する際にTagNameを渡してます、v8の場合は以下の書き方になってます。

v8

main.go
var validate *validator.Validate
config := &validator.Config{TagName: "validate"}
validate = validator.New(config)

v9以降のTagNameのデフォルト値が validateに指定されてます、ライブラリのソースコードを見てみよう。

validator_instance.go

    v := &Validate{
        tagName:     defaultTagName,
        aliases:     make(map[string]string, len(bakedInAliases)),
        validations: make(map[string]internalValidationFuncWrapper, len(bakedInValidators)),
        tagCache:    tc,
        structCache: sc,
    }
validator_instance.go
const (
    defaultTagName        = "validate"

よって、v9以降特に指定がなければ、以下の書き方になります。

v9以降

main.go
validate = validator.New()

validator.RegisterValidation

カスタムバリデーションを作る際にvalidator.RegisterValidation()が使われます。
v8の場合以下の書方になっていました、戻り値の真偽で判断しています。

v8

main.go
...
v.RegisterValidation("bookabledate", bookableDate)
...

func bookableDate(
  v *validator.Validate, topStruct reflect.Value, currentStructOrField reflect.Value,
  field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string,
) bool {
  if date, ok := field.Interface().(time.Time); ok {
      today := time.Now()
      if date.Unix()>today.Unix(){
          return true
      }
  }
  return false
}

v9以降では、使い方は変わってないですが、検証用の関数を受けるパラメーターが簡略化されました。
fieldパラメーターなどは validator.FieldLevelに集約されました。

v9以降

main.go
...
v.RegisterValidation("bookabledate", bookableDate)
...
func bookableDate(fl validator.FieldLevel) bool {
    if  date,ok:=fl.Field().Interface().(time.Time);ok{
        today:=time.Now()
        fmt.Println("date:",date)
        if date.Unix()>today.Unix(){
            fmt.Println("date unix :",date.Unix())
            return true
        }
    }
    return false
}

validator.ValidationErrors

  • v8の validator.ValidationErrorsのタイプは map[string]*FieldError
    • FieldErrorは構造体
  • v9以降の validator.ValidationErrorsのタイプは ValidationErrors []FieldError
    • FieldErrorはインターフェース

v8では以下のような書き方でFieldErrorを生成していましたが、v9以降では使えません。

v8

main.go
validator.ValidationErrors{err: &karma.InvalidParamError{
    "xx.yy": &validator.FieldError{Field: "yy", Tag: "gt"},Err: errors.New(fmt.Sprintf(fieldErrMsg, "xx.yy", "yy", "gt")),
}

v9以降で同じエラーを生成したい場合、fieldErrorの Error()関数の書き方を真似するといいです。

errors.go
const fieldErrMsg = "Key: '%s' Error:Field validation for '%s' failed on the '%s' tag"

func (fe *fieldError) Error() string {
    return fmt.Sprintf(fieldErrMsg, fe.ns, fe.Field(), fe.tag)
}

v9以降

mian.go
const fieldErrMsg = "Key: '%s' Error:Field validation for '%s' failed on the '%s' tag"
validator.ValidationErrors{err: errors.New(fmt.Sprintf(fieldErrMsg, "xx.yy", "yy", "gt"))}
1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0