AIによる要約
Formクラスは画面やリクエストから入力値を受け取るためのクラス、DTOは層の間でデータを受け渡すためのクラスとして使われます。現場では名前だけでなく、どの層の都合を表すクラスなのかを分けることが重要です。


Spring Bootの業務システムでは、Form、DTO、Entityのような値を入れるクラスがたくさん出てきます。
初学者にとっては、どれもフィールドとgetter/setterを持つ似たクラスに見えます。しかし、現場では役割を混ぜると後から修正しづらくなります。
この記事のポイント
- Formクラスは画面やリクエストの入力都合を表す
- DTOは層の間のデータ受け渡しに使う
- Entityを画面入力に直接使うのは避ける
- 名前ではなく、どの層の都合を表すかで判断する
Formクラスは画面入力の都合を表す
Formクラスは、画面やリクエストから入力された値を受け取るためのクラスです。画面の入力欄、チェックボックス、セレクトボックスなどと対応しやすい形になります。
public class UserRegisterForm {
@NotBlank
private String name;
@NotBlank
@Email
private String email;
private String departmentCode;
}
Formクラスには、画面入力として必要な制約や、未入力時の扱いが入ります。つまり、画面側の事情を受け止めるクラスです。
DTOは層の間の受け渡しに使う
DTOは、Data Transfer Objectの略で、データを受け渡すためのクラスです。Serviceの入力、Controllerへのレスポンス、外部APIとのやり取りなど、使われる場所はプロジェクトによって変わります。
public class UserRegisterCommand {
private final String name;
private final String email;
private final String departmentCode;
public UserRegisterCommand(String name, String email, String departmentCode) {
this.name = name;
this.email = email;
this.departmentCode = departmentCode;
}
}
この例では、画面入力のFormをそのままServiceへ渡すのではなく、業務処理に必要な形へ変換しています。プロジェクトによってはCommand、Request、DTOなど名前は違います。
同じクラスで済ませると何が困るか
小さい機能では、FormもDTOも同じに見えます。しかし、画面の都合と業務処理の都合はズレることがあります。
// 画面では文字列で受けたい private String birthDate; // Serviceでは日付として扱いたい private LocalDate birthDate;
画面では未入力や表示形式の都合で文字列にしたい一方、ServiceではLocalDateとして扱いたいことがあります。同じクラスにすると、どちらかの都合を無理に押し込むことになります。
EntityをForm代わりにしない
新人がやりがちな危険な実装は、Entityをそのまま画面フォームに使うことです。
@PostMapping("/users")
public String register(@Valid User user) {
userRepository.save(user);
return "redirect:/users";
}
これは簡単に見えますが、画面で入力させたくない項目まで更新対象になったり、DB構造が画面に漏れたりします。現場では避けることが多いです。
変換処理はどこに置くか
FormからDTOやCommandへ変換する場所は、プロジェクト方針によります。小さい機能ならControllerで変換してもよいですが、変換が複雑なら専用メソッドを用意します。
@PostMapping("/users")
public String register(@Valid UserRegisterForm form,
BindingResult bindingResult) {
if (bindingResult.hasErrors()) {
return "users/new";
}
UserRegisterCommand command = form.toCommand();
userService.register(command);
return "redirect:/users";
}
ここで大事なのは、Serviceが画面の細かい都合を知りすぎないことです。Serviceには、業務処理に必要な形の値を渡すと読みやすくなります。
現場レビューではどう見られるか
// レビューコメント例 EntityをFormとして使うのは避けたいです。 画面入力用のFormクラスを作って、Serviceに渡す形へ変換してください。 // レビューコメント例 このDTOは画面入力用なのか、Serviceへ渡すためなのか役割が曖昧です。 名前か置き場所で意図が分かるようにしましょう。
レビュー前のセルフチェック
確認リスト
- Formクラスに画面入力以外の責務を入れていないか
- DTOがどの層の受け渡し用か名前から分かるか
- Entityをそのまま画面入力に使っていないか
- FormからService用の値へ変換する場所が説明できるか
この記事とあわせて読みたい
- Spring Bootの@RequestParamとFormクラスの違いは?使い分けを解説
- Spring Bootの@ModelAttributeとは?Formに値が入る仕組みと使い方
- Spring BootのDTO変換はどこでやるべきか
まとめ
Formクラスは画面入力の都合を受けるクラス、DTOは層の間でデータを受け渡すクラスとして考えると整理しやすいです。
新人のうちは、クラスの中身だけでなく、どの層の都合を表しているのかを見る癖を付けると、Spring Bootの現場コードを読みやすくなります。
