【ITニュース解説】Simplify Validation in Golang— No Struct Tags, No Reflection, TypeSafety: Meet GoValidator
2025年09月05日に「Dev.to」が公開したITニュース「Simplify Validation in Golang— No Struct Tags, No Reflection, TypeSafety: Meet GoValidator」について初心者にもわかりやすいように丁寧に解説しています。
ITニュース概要
GoのバリデーションライブラリGoValidatorは、structタグやリフレクションを使わず、シンプルで高速な検証を実現。RequiredInt、Email、Existsなど豊富なルールを標準装備し、CustomRuleで独自ルールも追加可能。データベース連携もサポートし、複雑な条件も記述できる。インストールは `go get github.com/rezakhademix/govalidator/v2`。
ITニュース解説
Goにおけるデータ検証は、これまで複雑なライブラリや構造体タグに依存することが多かった。GoValidatorは、これらの複雑さを排除し、シンプルで高速な検証を実現するライブラリだ。
GoValidatorの主な特徴は以下の通り。構造体タグが不要なこと、リフレクションを使用しないこと、軽量で拡張可能なことだ。構造体タグは、データ構造に検証ルールを埋め込む方法だが、コードの可読性を損なう可能性がある。GoValidatorでは、タグを使わずに、検証ルールを直接コードに記述できる。また、リフレクションは、プログラム実行時に型情報を操作する技術だが、パフォーマンスに影響を与えることがある。GoValidatorはリフレクションを使用しないため、高速な検証が可能になる。さらに、カスタムルールを定義できるため、独自の検証要件にも対応できる。
GoValidatorのインストールとインポートは簡単だ。
go get github.com/rezakhademix/govalidator/v2
でインストールし、
import validator "github.com/rezakhademix/govalidator/v2"
でインポートする。
GoValidatorには、多くの組み込み検証ルールが用意されている。基本的なチェックとして、RequiredInt(必須整数)、RequiredFloat(必須浮動小数点数)、RequiredString(必須文字列)、RequiredSlice(必須スライス)がある。範囲検証には、BetweenInt(整数範囲)、BetweenFloat(浮動小数点数範囲)、BetweenString(文字列長範囲)、In(列挙型)がある。特殊なチェックとして、Date(日付)、Email(メールアドレス)、URL(URL)、UUID(UUID)がある。データベースチェックには、Exists(存在確認)、NotExists(非存在確認)、ExistExceptSelf(自身以外に存在確認)がある。高度なロジックとして、CustomRule(カスタムルール)、When(条件付き検証)、RegexMatches(正規表現マッチ)、Time(時刻)、Date(日付)がある。
GoValidatorを使うメリットは、シンプルさ、拡張性、パフォーマンスだ。ボイラープレートコードやタグが不要で、検証が直接的になる。CustomRule()メソッドで独自のルールを定義できる。リフレクションを避けることで、高速化とオーバーヘッド削減が実現する。
具体的な使用例を見てみよう。サインアップフォームの検証を想定する。
1v := validator.New() 2 3ok := v. 4 RequiredString(username, "username", "username is required"). 5 Email(email, "email", "email is required"). 6 BetweenInt(age, 18, 60, "age", "age must be between 18 and 60"). 7 IsPassed() 8 9if !ok { 10 log.Println("validation failed, errors:", v.Errors()) 11}
この例では、usernameが必須文字列、emailがメールアドレス形式、ageが18歳から60歳の間であることを検証している。
より複雑な例として、カテゴリ作成リクエストの検証を見てみよう。
1type CategoryCreateReq struct { 2 ParentID *int 3 Name string 4 Description string 5 Status int 6 Meta string 7} 8 9var req CategoryCreateReq 10 11v := validator.New() 12 13ok := v. 14 RequiredString(req.Name, "name", "name of category is required"). 15 MaxString(req.Name, 500, "name", "name should be less than 500 characters"). 16 MinString(req.Name, 3, "name", "name should be more than 3 characters"). 17 NotExists(req.Name, "categories", "name", "name", "name already exists"). // ensure req.Name is unique in DB 18 MaxString(req.Description, 1500, "description", "description should be less than 1500 characters"). 19 MinInt(req.Status, 1, "status", "status can not be less than 1"). 20 MaxInt(req.Status, 12, "status", "status can not be more than 12"). 21 IsJSON(req.Meta, "meta","meta should be JSON"). 22 When(req.ParentID != nil, func() { 23 v.Exists(*req.ParentID, "categories", "id", "parent_id","parent doest not exists") 24 }). 25 IsPassed() 26 27if !ok { 28 return v.Errors() 29}
この例では、カテゴリ名が必須で、長さが3文字以上500文字以下であること、データベース内で一意であること、説明文の長さが1500文字以下であること、ステータスが1から12の間であること、メタ情報がJSON形式であること、親IDが存在する場合にデータベースに存在することを確認している。特に、Whenを利用することで、ParentIDが設定されている場合のみ、親IDの存在チェックを行うように条件付きの検証を設定できる。
GoValidatorは、構造体タグを使わずにGoで構造体を検証するための優れた方法を提供する。構造体タグの代わりに、RequiredString、BetweenIntなどの明示的な検証メソッドを使用することで、検証ロジックを明確かつ型安全に保つことができる。また、CustomRule()を使用してGoValidatorを拡張し、独自の検証ロジックを統合することも可能だ。さらに、データベースルックアップのサポートも提供しており、Exists、NotExists、ExistExceptSelfなどのルールを使用して、データベースに基づいた検証も行える。これらの特徴により、GoValidatorは、Goでデータ検証を行うための強力で柔軟なツールとなる。