DDD 혹은 헥사고날 아키텍처에서는 계층마다 관심사와 책임이 다르기 때문에,
각 계층에 맞는 DTO를 별도로 두는 것이 권장됩니다.
@RequestBody, @RequestParam, @Valid와 함께 사용public class PostCreateRequest {
private String title;
private String content;
// Getter/Setter
}
xxxCommand, xxxQuery, xxxResponse 형식public class CreatePostCommand {
private final String title;
private final String content;
// 생성자 & Getter
}
Command 객체는 “무언가를 실행하라”는 명확한 의도를 담은 데이터 모델입니다.
단순히 데이터를 전달하는 DTO가 아니라, 유스케이스의 명령(Command)를 표현하는 것입니다.
예를 들어, 게시글을 생성하는 유스케이스에는 아래와 같은 Command 객체를 사용합니다:
public class CreatePostCommand {
private final String title;
private final String content;
...
}
| 이유 | 설명 |
|---|---|
| 유스케이스 중심 사고 | "어떤 작업을 할 것인지" 명확하게 표현 |
| 계층 간 책임 분리 | Web 계층과 Application 계층의 의존성 제거 |
| 코드 가독성 향상 | 메서드와 DTO가 1:1로 대응되어 추론 쉬움 |
[사용자 요청] ─▶ 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);
}
presentation
└─ controller
└─ dto
├─ request → PostCreateRequest
└─ response → PostResponse
application
└─ dto
└─ request → CreatePostCommand
└─ response → PostDto (optional)
└─ service → PostService
domain
└─ model → Post (Entity)
└─ repository → PostRepository
Controller의 DTO는 View/Web 친화적으로 만들고,Application의 DTO는 유스케이스 중심으로 설계하자.DDD 구조에서는 단순히 "DTO 하나로 끝"이 아닌,
계층에 맞게 역할을 분리하고,
유스케이스 중심으로 사고하는 Command 객체의 명명이 중요한 설계 포인트입니다.