前書き
今後同じ作業をする方と自分の振り返りのため、メモを残します。
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"))}