LoginSignup
2
3

More than 5 years have passed since last update.

gin frameworkにCustom Validatorを追加する

Last updated at Posted at 2016-09-25

Documentにはなかったので、ソースコードを読んでこうしてみました。

検証用の関数を作る

以下のように検証用の関数を作ります。

package myvalidator

import (
    "gopkg.in/go-playground/validator.v8"
    "reflect"
)

var MyValidations = map[string]validator.Func {
    "custom1": custom1,
    "custom2": custom2,
}

func Custom1(v *validator.Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
    if fieldKind == reflect.String {
        str := field.String()
        // 検証が通ればtrueを返す
        return true
    } else {
        return false
    }
}

func Custom2(v *validator.Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
    if fieldKind == reflect.String {
        str := field.String()
        // 検証が通ればtrueを返す
        return true
    } else {
        return false
    }
}

CustomValidatorを作る(検証関数の登録)

ginのbinding/default_validator.goを参考にしてValidatorを作る

package myvalidator

import (
    "sync"
    "gopkg.in/go-playground/validator.v8"
    "reflect"
)

type MyValidator struct {
    once     sync.Once
    validate *validator.Validate
}

func (v *MyValidator) ValidateStruct(obj interface{}) error {
    if kindOfData(obj) == reflect.Struct {
        v.lazyinit()
        if err := v.validate.Struct(obj); err != nil {
            return error(err)
        }
    }
    return nil
}

func (v *MyValidator) lazyinit() {
    v.once.Do(func() {
        config := &validator.Config{TagName: "binding"}
        // ここにrequiredなど元からあるValidationは含まれている
        v.validate = validator.New(config)
        // ここでValidation関数を登録
        for key, value := range MyValidations {
            v.validate.RegisterValidation(key, value)
        }
    })
}

func kindOfData(data interface{}) reflect.Kind {
    value := reflect.ValueOf(data)
    valueType := value.Kind()
    if valueType == reflect.Ptr {
        valueType = value.Elem().Kind()
    }
    return valueType
}

ginに作ったValidatorを設定

import (
    "github.com/gin-gonic/gin"
)

// gin.Default()を呼ぶ前に呼んで、ginのValidatorを初期化する
func initGinValidator() {
    binding.Validator = &myvalidator.MyValidations{}
}
2
3
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
2
3