Go/Echoで、APIのパラメータのバリデーションどうしようと調べて見つかったモジュールが「gopkg.in/go-playground/validator
」。
そのリファレンスの返却値部分のメモです。
使用モジュール
最新のメジャーバージョンはv10のようなのですが、gomodのプロキシ周りの設定?が怪しいのかリンクエラーが出まくってしまったため、本例ではv9を使っています。
(本当はgithub.comだけどgopkg.in使えとエラーが出てるがVSCodeだと補完できずエラーになる)
概要
- チェックしたい構造体にバリデーションルールを書いたタグを付与する
- validatorインスタンスのStructメソッドに、チェックしたい構造体のインスタンスを渡す
- 戻り値(error)がリストに入ったinterface型で返ってくるので、
validator.ValidationErrors
に型アサーションして使用する
例えばAPIの返却値としてエラー内容を構造化してクライアントに返すためには、3のvalidator.ValidationErrors
下のメソッドを使う必要があります。
サンプル
コピペでPlaygroundで動きます。
package main
import (
"fmt"
"gopkg.in/go-playground/validator.v9"
)
type paramUpdateUserInfo struct {
ID int `json:"id" validate:"required,gte=0"`
Name string `json:"name" validate:"required,min=10,max=100"`
Memo string `json:"memo"`
}
func main() {
param := paramUpdateUserInfo{
ID: 1,
Name: "あ",
}
if err := validator.New().Struct(param); err != nil {
for _, desc := range err.(validator.ValidationErrors) {
fmt.Println("Field: " + desc.Field())
fmt.Println("StructField: " + desc.StructField())
fmt.Println("Namespace: " + desc.Namespace())
fmt.Println("StructNamespace: " + desc.StructNamespace())
fmt.Println("Kind: " + desc.Kind().String()) // reflect
fmt.Println("Type: " + desc.Type().String()) // reflect
fmt.Println("Value: " + desc.Value().(string)) // interface
fmt.Println("Tag: " + desc.Tag())
fmt.Println("ActualTag: " + desc.ActualTag())
fmt.Println("Param: " + desc.Param())
}
}
}
メソッド
公式リファレンス
https://pkg.go.dev/gopkg.in/go-playground/validator.v9#FieldError
サンプルの前提
構造体名: paramUpdateUserInfo
validateタグ: validate:"required,min=10,max=100"
エラーがあるフィールド名: Name
エラー内容: 文字数不足エラー
メソッド | 文字列変換した場合の返却値 | 説明 |
---|---|---|
Field | Name | エラーが発生したフィールド名。 タグがある場合はその名前が優先される。 |
StructField | Name | エラーが発生したフィールド名(構造体の定義名)。 |
Namespace | paramUpdateUserInfo.Name | エラーが発生したフィールド名にネームスペースを付与したもの。 タグがある場合はその名前が優先される。 |
StructNamespace | paramUpdateUserInfo.Name | エラーが発生したフィールド名にネームスペースを付与したもの。 |
Kind | string | reflectのKind型が返却される。 Stringメソッドを使うことで、型を示す文字列を取得可能。 |
Type | string | reflectのType型が返却される。 Stringメソッドを使うことで、型を示す文字列を取得可能。 |
Value | あ | エラーが発生した値のinterface値。型アサーションが必要。 動的にKindを渡したいところですが、interfaceにreflectは渡せないらしくエラーになります。。(循環参照的な?) |
Tag | min | validateタグで設定され、失敗した検証内容。 エイリアスが設定されていた場合、実際の検証内容ではなくエイリアスが返却される。 例えばエイリアスが"iscolor": "hexcolor|rgb|rgba|hsl|hsla"の場合、返却値はiscolor。 |
ActualTag | min | validateタグで設定され、失敗した検証内容。 エイリアスが設定されていた場合、エイリアス名ではなく実際の検証内容が返却される。 例えばエイリアスが"iscolor": "hexcolor|rgb|rgba|hsl|hsla"の場合、返却値はhexcolor|rgb|rgba|hsl|hsla。 |
Param | 10 | validateタグで設定され、失敗した検証のパラメータ。しきい値など。 |
例えばフロントで「名前は10文字以上で設定してください」というエラーメッセージを作りたいとして、
欲しい情報は
- StructField (= Name)
- Tag (= min)
- Param (= 10)
辺りでしょうか?
半角数字のみで~とかそういうのはカスタムバリデーションで設定することになると思いますが、
この記事ではとりあえずここまで。
参考
https://qiita.com/RunEagler/items/ad79fc860c3689797ccc
https://qiita.com/ayatothos/items/064ce18f4260b2503249