DTO변환 위치 : Controller일까? Service일까?

2024. 1. 12. 09:04우아한테크코스/프리코스

결론 : 정답이 없다.

PostRequest는 toEntity()를 통해 PostRequest(DTO) → Entity로 변환이 가능하다.

@Getter
@Builder
@AllArgsConstructor(access = AccessLevel.PROTECTED)
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class PostRequest {

    private String title;
    private String content;
    private String writer;

    public Post toEntity() {
        return Post.builder()
                .title(title)
                .content(content)
                .writer(writer)
                .build();
    }
}
 

PostReponse에서는 Builder를 통해 Entity → DTO로 변환이 가능하다.

@Getter
@AllArgsConstructor(access = AccessLevel.PROTECTED)
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class PostResponse {

    private Long id;
    private String title;
    private String content;
    private String writer;

    @Builder
    public PostResponse(Post post) {
        this.id = post.getId();
        this.title = post.getTitle();
        this.content = post.getContent();
        this.writer = post.getWriter();
    }
}
 

위 Entity ↔ DTO간의 변환작업을 Controller에서 해야할까? Service에서 해야할까?

A. Entity ↔ DTO간의 변환작업을 ArticleController에서 해준 경우

  • ArticleController
@PostMapping
public ResponseEntity<ArticleResponseDto> createArticle(@RequestBody ArticleRequestDto articleRequestDto) {
    //로직 생략
    Article article = articleRequestDto.toEntity();
    Article savedArticle = articleService.createArticle(article);
    ArticleResponseDto articleResponseDto = ArticleResponseDto.from(savedArticle);
    return ResponseEntity.ok().body(articleResponseDto);
}
 
  • ArticleService
public Article createArticle(Article article) {
    //로직 생략
    return articleRepository.save(article);
}
 

B. Entity ↔ DTO간의 변환작업을 ArticleService에서 해준 경우

  • ArticleService
public ArticleDto createArticle(ArticleDto articleRequestDto) {
    Article article = articleRequestDto.toEntity();
    //로직 생략
    return ArticleDto.from(articleRepository.save(article));
}
 

A Case 문제점

  • 비즈니스 로직과 혼재
    • Controller가 여러 Domain객체들의 정보를 조합해서 DTO를 생성해야 하는 경우, 결국 Service(응용 계층) 로직이 Controller에 포함되게 됩니다.
    • 여러 Domain 객체들을 조회해야 하기 때문에 하나의 Controller가 의존하는 Service의 개수가 비대해집니다.

B Case문제점