DTO Pattern
DTOパターンを図で説明しますね。DTOパターンを図にしました。重要なポイントを説明します:
DTOパターンの目的
DTO (Data Transfer Object) は、異なる層の間でデータを運ぶための専用オブジェクトです。
主な特徴
1. データの分離
- Entity: データベースの構造を表現(内部情報を含む)
- DTO: 外部に公開する情報のみ含む(パスワードなど秘密情報を除外)
2. 利点
- セキュリティ向上(機密情報の漏洩防止)
- 疎結合(内部構造の変更が外部に影響しない)
- ネットワーク効率化(必要なデータのみ転送)
- API契約の明確化
3. 使用例
Entity(内部):
- password, createdAt, updatedAt など全てのフィールド
DTO(外部公開):
- id, name, email など公開して良いフィールドのみ
この分離により、データベース構造を変更してもAPIの互換性を保ちやすくなります。
graph TB
subgraph "Handler層 (Presentation)"
Handler[Handler<br/>http.HandlerFunc]
UserDTO[UserDTO struct<br/>- ID string json:id<br/>- Name string json:name<br/>- Email string json:email]
CreateDTO[CreateUserDTO<br/>- Name string json:name<br/>- Email string json:email<br/>- Password string json:password]
end
subgraph "Service層 (Business Logic)"
Service[UserService]
Mapper[Mapper関数<br/>EntToDTO / DTOToEnt]
end
subgraph "Ent ORM層"
Client[*ent.Client]
Schema[User Schema<br/>schema/user.go]
EntModel[*ent.User<br/>自動生成モデル<br/>- ID int<br/>- Name string<br/>- Email string<br/>- Password string<br/>- CreatedAt time.Time<br/>- UpdatedAt time.Time<br/>- Edges...]
Query[User Query Builder<br/>client.User.Query]
end
subgraph "Database"
DB[(PostgreSQL/MySQL)]
end
Handler -->|1. リクエスト受信| CreateDTO
CreateDTO -->|2. DTOを渡す| Service
Service -->|3. バリデーション| Mapper
Mapper -->|4. Ent用に変換| Client
Client -->|5. Create/Update| EntModel
EntModel -->|6. SQL生成| Query
Query -->|7. SQL実行| DB
DB -->|8. データ取得| Query
Query -->|9. *ent.User生成| EntModel
EntModel -->|10. Entityを返す| Client
Client -->|11. *ent.User| Service
Service -->|12. DTOに変換| Mapper
Mapper -->|13. UserDTO生成| UserDTO
UserDTO -->|14. JSON返却| Handler
Schema -.->|entc generate| EntModel
Schema -.->|entc generate| Query
style UserDTO fill:#e1f5ff
style CreateDTO fill:#e1f5ff
style EntModel fill:#fff4e1
style Schema fill:#ffe1f5
style Handler fill:#f0f0f0
style DB fill:#ffe1e1
style Mapper fill:#e1ffe1
Go EntでのDTOパターンの実装例を図にしますね。Go EntでのDTOパターンを図にしました!
Go Entの特徴
1. Entの自動生成
schema/user.goでスキーマ定義entc generateで*ent.Userモデルと Query Builder を自動生成- 型安全なクエリビルダーが使える
2. DTOとの使い分け
// スキーマ定義 (schema/user.go)
type User struct {
ent.Schema
}
// 自動生成される Ent モデル
type User struct {
ID int
Name string
Email string
Password string // 🔒 外部に公開したくない
CreatedAt time.Time
UpdatedAt time.Time
}
// 手動で作成する DTO
type UserDTO struct {
ID string `json:"id"`
Name string `json:"name"`
Email string `json:"email"`
// Passwordは含めない!
}
3. Mapper関数の例
// Ent → DTO
func EntToDTO(u *ent.User) UserDTO {
return UserDTO{
ID: strconv.Itoa(u.ID),
Name: u.Name,
Email: u.Email,
}
}
// DTO → Ent (Create時)
func CreateUser(ctx context.Context, dto CreateUserDTO) (*ent.User, error) {
return client.User.Create().
SetName(dto.Name).
SetEmail(dto.Email).
SetPassword(hashPassword(dto.Password)).
Save(ctx)
}
Entは内部のデータ管理に特化し、DTOは外部とのやり取りに特化させることで、安全で保守性の高いコードになります。