1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Go言語におけるバリデーションモジュールの返却値の覚え書き

Last updated at Posted at 2021-05-06

Go/Echoで、APIのパラメータのバリデーションどうしようと調べて見つかったモジュールが「gopkg.in/go-playground/validator」。
そのリファレンスの返却値部分のメモです。

使用モジュール

最新のメジャーバージョンはv10のようなのですが、gomodのプロキシ周りの設定?が怪しいのかリンクエラーが出まくってしまったため、本例ではv9を使っています。
(本当はgithub.comだけどgopkg.in使えとエラーが出てるがVSCodeだと補完できずエラーになる)

概要

  1. チェックしたい構造体にバリデーションルールを書いたタグを付与する
  2. validatorインスタンスのStructメソッドに、チェックしたい構造体のインスタンスを渡す
  3. 戻り値(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://play.golang.org/p/ibPUaf7fE_B

メソッド

公式リファレンス
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

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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?