DTOとは
DTO とは Data Transfer Object(データ転送オブジェクト) の略で、
システム内部の別レイヤー間でデータを受け渡すための専用のオブジェクトです。
DTOクラスの実装
DTOクラスの実装には、以下の要素が必要になります。
- Book(Entity) に対応する「リクエスト専用 DTO」
- リクエスト専用 DTOにバリデーションのチェック内容を指定
- Book(Entity) に対応する「レスポンス専用 DTO」
- Book(Entity) から レスポンス専用 DTO を作成するためのユーティリティメソッド
実装例:
package com.example.demo.web.dto;
import jakarta.validation.constraints.*;
// 1.Book(Entity) に対応する「リクエスト専用 DTO」
public record BookRequest(
// 2.バリデーションのチェック内容を指定
@NotBlank @Size(max=120) String title,
@NotBlank @Size(max=80) String author,
@PositiveOrZero Integer price
) {}
package com.example.demo.web.dto;
import com.example.demo.domain.Book;
import java.time.LocalDateTime;
// 3. Book(Entity) に対応する「レスポンス専用 DTO」
public record BookResponse(
Long id, // Book の ID
String title, // タイトル
String author, // 著者
Integer price, // 価格
LocalDateTime createdAt, // 作成日時
LocalDateTime updatedAt // 更新日時
) {
// 4. Book(Entity) から レスポンス専用 DTO を作成するためのユーティリティメソッド
public static BookResponse of(Book b) {
return new BookResponse(
b.getId(), // Book の id
b.getTitle(), // Book のタイトル
b.getAuthor(), // Book の著者
b.getPrice(), // Book の価格
b.getCreatedAt(), // 作成日時
b.getUpdatedAt() // 更新日時
);
}
}
1. Book(Entity) に対応する「リクエスト専用 DTO」
public record BookRequest(
クライアント(HTMLフォーム・JavaScript・APIクライアント等)から送られてくるデータを受け取るためのクラスを定義しています。
record を使うことで、フィールドを自動生成します。(getter、equals、hashCode、toString)
2. リクエスト専用 DTOにバリデーションのチェック内容を指定
@NotBlank @Size(max=120) String title,
@NotBlank @Size(max=80) String author,
@PositiveOrZero Integer price
バリデーション(validation) =「入力チェック」のことです。
タイトルが空のまま送られてこないか?
文字数が長すぎないか?
価格がマイナスになっていないか?
こういったチェックを 毎回自分で if 文で書くのではなく、
アノテーション(@〇〇)で簡単に指定できるのが Bean Validation(Jakarta Validation) です。
Spring MVC では、コントローラで @Valid / @Validated を付けるだけで
この BookRequest に書かれたチェックが自動で実行されます。
必須チェック(null / 空文字 など)
| アノテーション | 説明 | null | ""(空文字) | " "(空白だけ) |
|---|---|---|---|---|
| @NotNull | null を禁止 | NG | OK | OK |
| @NotEmpty | null ・空文字を禁止 | NG | NG | OK |
| @NotBlank | null・空文字・空白を禁止 | NG | NG | NG |
長さ・サイズチェック
| アノテーション | 説明 |
|---|---|
| @Size(min=, max=) | 文字列・配列・リストなどのサイズ(文字数)を制限 |
数値チェック
| アノテーション | 説明 |
|---|---|
| @Positive | 1 以上(正の数) |
| @PositiveOrZero | 0 以上 |
| @Negative | -1 以下(負の数) |
| @NegativeOrZero | 0 以下 |
| @Min(n) | 最小値を指定 |
| @Max(n) | 最大値を指定 |
日付・過去未来チェック
| アノテーション | 説明 |
|---|---|
| @Past | 過去の日付のみ |
| @PastOrPresent | 過去・今日まで |
| @Future | 未来の日付のみ |
| @FutureOrPresent | 今日以降 |
形式チェック
| アノテーション | 説明 |
|---|---|
| メールアドレス形式 | |
| @Pattern(regexp = "...") | 正規表現でチェック |
3. Book(Entity) に対応する「レスポンス専用 DTO」
public record BookResponse(
Long id, // Book の ID
String title, // タイトル
String author, // 著者
Integer price, // 価格
LocalDateTime createdAt, // 作成日時
LocalDateTime updatedAt // 更新日時
) {
API などの外部公開値を返すためのクラスを定義しています。
record を使うことで、フィールドを自動生成します。(getter、equals、hashCode、toString)
4. Book(Entity) から レスポンス専用 DTO を作成するためのユーティリティメソッド
public static BookResponse of(Book b) {
return new BookResponse(
b.getId(), // Book の id
b.getTitle(), // Book のタイトル
b.getAuthor(), // Book の著者
b.getPrice(), // Book の価格
b.getCreatedAt(), // 作成日時
b.getUpdatedAt() // 更新日時
);
}
サービス層やコントローラで簡単に DTO を生成できるようにするための関数です。
主にレスポンスを返す際に、データ型を変換するために使用します。