lvncerpedia

DTO(Data Transfer Object)とは

簡単に言うと、「データを運ぶ専用の入れ物」 のこと! ORMで取ってきたエンティティ(DBの構造に依存したオブジェクト)をそのまま外に渡すんじゃなくて、必要な情報だけ詰め替えた別オブジェクトを作って渡すって感じ。

なんで分けるの?

ORMのエンティティをそのまま使い回すと…

  • セキュリティ的にヤバい — パスワードとか秘密情報まで外に漏れちゃう
  • DBの変更がすぐ影響する — カラム名変えただけで全部壊れる
  • 余計なデータまで渡しちゃう — 関係ないフィールドがいっぱいついてくる

イメージ図

DBテーブル
  ↓ ORM
Entityクラス(DB構造そのまま)
  ↓ 詰め替え(Mapper)
DTOクラス(必要な情報だけ)
  ↓
Controller / View / API

コード例(TypeScript風)

// ❌ これをそのまま返すのはNG
class UserEntity {
  id: number;
  name: string;
  email: string;
  passwordHash: string; // 危ない!
  createdAt: Date;
}

// ✅ DTOに詰め替えて返す
class UserDTO {
  id: number;
  name: string;
  email: string;
  // passwordHashは入れない!
}

// Mapperで変換
function toUserDTO(entity: UserEntity): UserDTO {
  return {
    id: entity.id,
    name: entity.name,
    email: entity.email,
  };
}

CQRSとの違いは?

DTOCQRS
目的データの詰め替え・隠蔽読み書きの処理フロー自体を分離
規模感小〜中規模でも普通に使う大規模・複雑なシステム向け
関係CQRSの中でDTOを使うことも多いDTOより大きな概念

DTOはシンプルだけどすごく大事な考え方で、わりとどこでも使えるやつだよ!