MicronautのValidation AOPで入力チェックを自動化する方法
生徒
「Micronautでフォーム入力やAPIリクエストの値を自動でチェックする方法はありますか?」
先生
「はい、MicronautではValidation AOPを使うと、アノテーションを付けるだけで入力値のバリデーションを自動化できます。」
生徒
「AOPを使うとどうして自動でチェックできるんですか?」
先生
「AOPはメソッドの呼び出し前に処理を挟むことができます。バリデーションアノテーションがついたパラメータやメソッドを呼ぶ前に、自動的にチェックが行われる仕組みです。」
1. Validation AOPとは?
MicronautのValidation AOPは、メソッドやパラメータに付与したバリデーションアノテーションをもとに、入力値が正しいかを自動で検証する仕組みです。これにより、個別にバリデーションコードを書く必要がなくなり、コードがシンプルになり、保守性も向上します。
2. 基本的なバリデーションアノテーション
Micronautではjavax.validationのアノテーションを利用できます。代表的なものとして@NotNullや@Size、@Min、@Maxがあります。これらを使うことで、簡単に入力チェックを実装できます。
import jakarta.inject.Singleton;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;
@Singleton
public class UserService {
public void registerUser(@NotNull @Size(min = 3, max = 20) String username) {
// ユーザー登録処理
}
}
3. メソッド単位でのバリデーション有効化
Micronautでは@Validatedアノテーションをクラスやメソッドに付与することで、Validation AOPが有効になります。これにより、バリデーションアノテーションが付いたパラメータに対して自動チェックが行われます。
import io.micronaut.validation.Validated;
import jakarta.inject.Singleton;
import jakarta.validation.constraints.Min;
@Singleton
@Validated
public class OrderService {
public void placeOrder(@Min(1) int quantity) {
// 注文処理
}
}
4. バリデーション失敗時の挙動
入力値が指定した条件を満たさない場合、Validation AOPが自動的に例外ConstraintViolationExceptionをスローします。これにより、メソッド内部の処理は実行されず、リクエストは失敗として扱われます。
try {
userService.registerUser(""); // ユーザー名が空なので失敗
} catch (jakarta.validation.ConstraintViolationException e) {
e.getConstraintViolations().forEach(v -> System.out.println(v.getMessage()));
}
5. DTOクラスを使った入力チェック
複数のパラメータをまとめてバリデーションしたい場合はDTOクラスを作成してアノテーションを付与します。メソッドにはDTOを受け取る形にすると、Validation AOPが自動でチェックします。
import jakarta.validation.constraints.NotBlank;
public class CreateUserRequest {
@NotBlank
private String name;
@NotBlank
private String email;
// getter, setter
}
@Singleton
@Validated
public class UserController {
public void createUser(CreateUserRequest request) {
// バリデーション済みのユーザー情報で処理
}
}
6. RESTコントローラでの自動バリデーション
MicronautのHTTPコントローラでは、@Bodyで受け取ったリクエストDTOにValidation AOPが自動適用されます。入力が不正な場合は400 Bad Requestとしてレスポンスが返されます。
import io.micronaut.http.annotation.*;
@Controller("/users")
@Validated
public class UserHttpController {
@Post("/")
public void create(@Body CreateUserRequest request) {
// バリデーション済みのリクエストで処理
}
}
7. カスタムバリデータの作成
標準アノテーションだけでは足りない場合、独自のカスタムバリデータを作成してValidation AOPで使用することも可能です。これにより複雑なルールにも対応できます。
import jakarta.validation.Constraint;
import jakarta.validation.Payload;
import java.lang.annotation.*;
@Documented
@Constraint(validatedBy = CheckPasswordValidator.class)
@Target({ ElementType.FIELD, ElementType.PARAMETER })
@Retention(RetentionPolicy.RUNTIME)
public @interface CheckPassword {
String message() default "パスワードが無効です";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
8. Validation AOPのメリット
Validation AOPを活用すると、入力チェックの重複コードが不要になり、メソッド呼び出し前に自動でバリデーションが行われます。これにより、開発者はビジネスロジックに集中でき、コードの可読性と保守性が向上します。