TIL_20250409_DDD 구조,DTO 분리 전략

Kim jisu·2025년 4월 9일

TIL

목록 보기
31/43

🧭 1. DDD 구조 속 계층별 DTO 역할

DDD 혹은 헥사고날 아키텍처에서는 계층마다 관심사와 책임이 다르기 때문에,
각 계층에 맞는 DTO를 별도로 두는 것이 권장됩니다.

✅ Controller 계층의 DTO (Web Request/Response DTO)

  • 역할: HTTP 요청/응답을 매핑
  • 특징:
    • 주로 @RequestBody, @RequestParam, @Valid와 함께 사용
    • 클라이언트 친화적: snake_case나 필드명 자유도 높음
    • JSON 직렬화/역직렬화 중심
public class PostCreateRequest {
    private String title;
    private String content;
    // Getter/Setter
}

✅ Application 계층의 DTO (Command / Query)

  • 역할: 유스케이스의 입력 또는 출력 모델
  • 특징:
    • 비즈니스 중심
    • 프레임워크와 무관한 순수 Java 객체
    • 보통 xxxCommand, xxxQuery, xxxResponse 형식
public class CreatePostCommand {
    private final String title;
    private final String content;
    // 생성자 & Getter
}

✍️ 2. Command 객체를 사용하는 이유

🎯 Command란?

Command 객체는 “무언가를 실행하라”는 명확한 의도를 담은 데이터 모델입니다.
단순히 데이터를 전달하는 DTO가 아니라, 유스케이스의 명령(Command)를 표현하는 것입니다.

예를 들어, 게시글을 생성하는 유스케이스에는 아래와 같은 Command 객체를 사용합니다:

public class CreatePostCommand {
    private final String title;
    private final String content;
    ...
}

💡 왜 굳이 Command로 나눌까?

이유설명
유스케이스 중심 사고"어떤 작업을 할 것인지" 명확하게 표현
계층 간 책임 분리Web 계층과 Application 계층의 의존성 제거
코드 가독성 향상메서드와 DTO가 1:1로 대응되어 추론 쉬움

🧩 3. 전체 흐름 예시 – 게시글 생성

[사용자 요청] ─▶ Controller(PostCreateRequest)
                    ↓
            CreatePostCommand로 변환
                    ↓
         Application Service(createPost)
                    ↓
           Domain Model(Post) 생성
                    ↓
         Repository(postRepository.save)

👇 예시 코드 요약

Controller → Web DTO

@PostMapping
public ResponseEntity<Void> create(@RequestBody PostCreateRequest request) {
    CreatePostCommand command = new CreatePostCommand(request.getTitle(), request.getContent());
    postService.createPost(command);
    return ResponseEntity.ok().build();
}

Application → Command 처리

public void createPost(CreatePostCommand command) {
    Post post = new Post(command.getTitle(), command.getContent());
    postRepository.save(post);
}

📁 4. 각 계층 DTO 구조 예시

presentation
 └─ controller
     └─ dto
         ├─ request → PostCreateRequest
         └─ response → PostResponse

application
 └─ dto
     └─ request → CreatePostCommand
     └─ response → PostDto (optional)
 └─ service → PostService

domain
 └─ model → Post (Entity)
 └─ repository → PostRepository

🧼 5. 실전 팁

  • Controller의 DTO는 View/Web 친화적으로 만들고,
  • Application의 DTO는 유스케이스 중심으로 설계하자.
  • 매핑은 Controller에서 명시적으로 수행하거나 Mapper 클래스를 활용해도 좋다.

✅ 마무리

DDD 구조에서는 단순히 "DTO 하나로 끝"이 아닌,
계층에 맞게 역할을 분리하고,
유스케이스 중심으로 사고하는 Command 객체의 명명이 중요한 설계 포인트입니다.

profile
Dreamer

0개의 댓글