はじめに
Spring Boot の API を作っていると、
DTO(Data Transfer Object)
という言葉をよく目にします。
- DTO って何?
- Entity と何が違うの?
- どこで使うの?
- 使わなくても動くのに、なぜ必要?
こういった疑問は、実務でもとても多いです。
この記事では、DTO の役割を
やさしく・実務寄り で整理していきます。
まずはコードから見ていきましょう。
DTO とは
一言でいうと、
「Controller と Service の間でデータを受け渡すための“入れ物”」
です。
- リクエストを受け取るための DTO
- レスポンスを返すための DTO
この 2 種類がよく使われます。
DTO の基本例
リクエスト DTO
public class UserRequest {
private String name;
private int age;
}レスポンス DTO
public class UserResponse {
private String name;
private int age;
}Controller は DTO を受け取り、
Service は DTO を返します。
DTO の役割を具体的に整理する
Controller と Service の境界を明確にする
DTO を使うことで、
「外から来るデータ」 と 「内部のデータ」 を分けられます。
例:
- 外部 → JSON → DTO
- 内部 → Entity(DB のデータ)
これにより、 Controller と Service の責務がきれいに分離されます。
Entity を外に出さない(セキュリティ・保守性)
Entity をそのまま返すと、
- 不要なフィールドが外に漏れる
- DB の構造が API に露出する
- 変更に弱くなる
という問題が起きます。
DTO を使えば、 外に見せたい情報だけを返せる ため安全です。
バリデーションを行いやすい
リクエスト DTO に @Valid を付けることで、
入力チェックを簡単にできます。
public class UserRequest {
@NotBlank
private String name;
@Min(0)
private int age;
}Controller で形式的なチェックを行い、
Service では業務的なチェックを行うという分離ができます。
レスポンスの形を自由に設計できる
レスポンス DTO を使うことで、 API の返却形式を柔軟に設計できます。
例:
- 必要なフィールドだけ返す
- ネストしたオブジェクトを返す
- 計算結果を含める
public class UserDetailResponse {
private String name;
private int age;
private List<OrderResponse> orders;
}API の仕様が明確になる
DTO を使うことで、
「この API は何を受け取り、何を返すのか」
がコードだけで明確になります。
ドキュメントとしても機能します。
DTO を使わないとどうなる?
Entity が外に漏れる
DB の構造が API に露出し、変更に弱くなります。
Controller が複雑になる
パラメータを個別に受け取る必要があり、
メソッドが肥大化します。
Service の責務が曖昧になる
入力と出力の形式がバラバラになり、
ロジックが散らばります。
DTO と Entity の違いを整理
| 項目 | DTO | Entity |
|---|---|---|
| 目的 | データの受け渡し | DB のデータを表現 |
| 層 | Controller / Service | Repository / DB |
| 変更 | API に合わせて自由 | DB に合わせる必要あり |
| バリデーション | 形式的なチェック | 業務的な制約(場合による) |
| 外部公開 | OK | NG(基本) |
この表だけで、実務の 8 割は理解できます。
実務でよくある DTO の種類
リクエスト DTO
外部からの入力を受け取る。
レスポンス DTO
外部に返すデータを整形する。
内部 DTO(Service 間の受け渡し)
複雑な処理を分けるために使うこともあります。
DTO をもっと活かすポイント
ModelMapper / MapStruct を使う
DTO ↔ Entity の変換を自動化できます。
Validation と組み合わせる
入力チェックが Controller で完結します。
ResponseEntity と組み合わせる
レスポンスの形がより明確になります。
まとめ
DTO は、
「Controller と Service の間でデータを安全・明確に受け渡すための入れ物」
です。
- Entity を外に出さない
- 入力チェックがしやすい
- レスポンスの形を自由に設計できる
- API の仕様が明確になる
- 三層アーキテクチャと相性抜群
難しく聞こえますが、
「外とのやり取りは DTO、内部のデータは Entity」
と理解できれば十分です。

DTO を理解すると、
Controller と Service の境界が一気にクリアになります。
データの受け渡しが整理されるだけで、
設計もテストもぐっと楽になります。
あなたの開発が、今日より少しだけ楽になりますように。

外に見せる用の入れ物って、なんだかおしゃれだね…

コメント