Validation
バリデーションは、オブジェクトの値が受け入れ可能かどうかを確認し、見つかった問題をすべて報告する仕組みです。
なぜ必要か
入力はさまざまな場所から来ます。リクエストボディ、フォーム、設定ファイル、キューからのメッセージなどです。それぞれの値には確認が必要です。名前が空白でないこと、年齢が 18 以上であること、メールアドレスがその形をしていることなどです。こうした確認を if 文で毎回書くのは繰り返しが多く、書き忘れも起きやすくなります。
バリデーションでは、ルールをプロパティのアノテーションとして一度だけ書きます。バリデータがアノテーションを読み、破られたルールをすべて報告します。各エラーにはエラーコードが付くので、メッセージファイルでユーザー向けの文に変えられます。
自分のコードが生成し、すでに信頼できる値には必要ありません。型の確認にも必要ありません。それは Dart の型システムが行います。
短い例
import 'package:spring_core_dart/spring_core_dart.dart';
// @Introspected lets the generator describe the properties,
// so the validator can read them without reflection.
@Introspected()
class SignupForm {
@NotBlank()
@Size(max: 20)
String name = '';
@NotNull()
@Email()
String? email;
@Min(18)
int age = 0;
}
import 'package:my_app/src/beans.dart';
import 'package:my_app/src/signup_form.dart';
import 'package:spring_core_dart/spring_core_dart.dart';
const log = SpringLog('signup');
void main() {
final context = ApplicationContext.run([appBeans]);
// Use the context's introspector: it knows the application's classes.
final validator = BeanValidator(
introspector: context.getBean<BeanIntrospector>(),
);
final form = SignupForm()
..name = 'Ada'
..age = 17;
for (final violation in validator.validateObject(form)) {
// email: must not be null
// age: must be greater than or equal to 18
log.warning('${violation.propertyPath}: ${violation.message}');
}
context.close();
}
モジュール appBeans はアプリケーションで一度だけ @ComponentScan() final BeanModule appBeans = $appBeans; として宣言します(Beans を参照)。
自分で呼ばなくても検証が行われる場所
- Bean クラスに付けた
@Validated()は、そのメソッドの引数と戻り値を検証します。違反があるとConstraintViolationExceptionが投げられます。メソッドバリデーション を参照してください。 @ConfigurationPropertiesクラスに付けた@Validated()は、アプリケーションの起動時にバインドされた設定値を検証します。不正な値があると起動が止まります。Configuration を参照してください。- Web スターターでは、
@RequestBodyパラメータに付けた@Valid()がボディを検証します。違反があると、フィールドを列挙した 400 レスポンスが返ります。
それ以外の場合は、BeanValidator を自分で呼ぶか、DataBinder を使って文字列の入力をオブジェクトにコピーし、同時に検証します。
このセクションのページ
- Constraints: 組み込みの制約アノテーションすべてと、そのパラメータ、独自の制約の書き方。
- Validator, Errors and DataBinder:
BeanValidator、手書きのValidator、結果を表すErrors、フォーム入力のバインド。 - メソッドバリデーション: 呼び出しのたびに引数と戻り値を検証する
@Validated()Bean。
Spring (Java) では
Java で対応するのは org.springframework.validation と Jakarta Bean Validation(通常は Hibernate Validator)の組み合わせです。
class SignupForm {
@NotBlank @Size(max = 20) private String name;
@NotNull @Email private String email;
@Min(18) private int age;
}
Set<ConstraintViolation<SignupForm>> violations = validator.validate(form);
重要な違い:
- クラスには
@Introspected()が必要です。ジェネレータがビルド時にプロパティを記述します。これがないクラスは検証されず、validateObjectは空のリストを返します。 intに付けた@Sizeのような制約の誤りは、実行時ではなくビルド時にエラーになります。- 3 つの制約は、Java の名前が Dart ですでに使われているため別のクラス名です。
@MustBeNull(Jakarta の@Null)、@Matches(@Pattern)、@FutureDate(@Future)。エラーコードは Jakarta の名前のままです。