go-playground/validator でバリデーションを実装する

こんにちは、まちいろの工藤です。

最近は Go ばかり書いているので、しばらく Go ネタを投稿していきます。今回はバリデーションの実装で利用している go-playground/validator を紹介したいと思います。

go-playground/validator とは

go-playground/validator は、Struct フィールドのタグにバリデーションルールを定義しておくことで、Struct 全体のバリデーションを行うことができます。

基本的な使い方

まずは Struct にバリデーションルールを記述します。required や max などは予め用意されているルールなので、このように定義するだけで使えます。

type Foo struct {
    ID `validate:"-"`
    Name `validate:"required,max=255"`
    Kana `validate:"max=255"`
}

あとは、この Struct を validator に渡すだけです。init などで *validator.Validate を初期化しておき、任意の箇所でバリデーションを実行します。

func init() {
    validate := validator.New()
}

func validate(foo *Foo) error {
    return validate.Struct(foo)
}

公式にサンプルがいくつかあるので、こちらも合わせて見てみると理解が深まります。

独自のバリデーションを実装する

`RegisterValidation` を使って、独自のバリデーションを追加することも可能です。下記は github.com/ttacon/libphonenumber を利用して、電話番号フォーマットをチェックするバリデーションの例です。

err := validate.RegisterValidation("phone", func(fl validator.FieldLevel) bool {
    _, err := libphonenumber.Parse(fl.Field().String(), "JP")
    return err == nil
})

複数のバリデーションをまとめたエイリアスを定義する

バリデーションの種類が増えていくと、Struct 側のバリデーション定義が煩雑になっていきます。そのような場合は `RegisterAlias` を使ってバリデーションをまとめます。

下記はメールアドレスフォーマット・255文字以内というバリデーションルール `app-email` を新たに登録する例です。アプリケーション内のルールに合わせてこのようなエイリアスを増やしていくと、Struct 側の定義がすっきりしますし、バリデーション定義漏れを防ぐことにも繋がります。

validate.RegisterAlias("app-email", "omitempty,email,max=255")

エラーメッセージをカスタマイズする

`validate.Struct` が返す error の実体は `validator.ValidationErrors` です。下記のように型アサーションを行い、独自のエラーメッセージに変換することも可能です。

if err != nil {
    for _, err := range err.(validator.ValidationErrors) {
        switch err.ActualTag() {
        case "required":
            return error.New(fmt.Sprintf("%s は必須です。", err.Field()))
        }
    }
}

return nil

最後に

いかがでしたでしょうか?go-playground/validator はシンプルかつ、かゆいところに手が届く素晴らしいライブラリだと思います。まだ使ったこと無い方はぜひ試してみてください。


<まちいろではエンジニアを絶賛募集中です!>


この記事が気に入ったらサポートをしてみませんか?