Dto는 어느 레이어까지 사용하는 것이 맞을까?

컨트롤러, 서비스, 레포지토리 레이어로 나누어진 스프링 웹 애플리케이션에서 컨트롤러의 DTO는 어느 레이어까지 전달하는 것이 좋을까?

레이어드 아키텍처?

먼저 레이어드 아키텍처의 목적에 대해서 생각해봤다. 레이어드 아키텍쳐는 복잡한 소프트웨어를 여러개의 레이어로 나누어 모듈화하는 것이다. 이렇게 하면 각 설계 요소가 분리되면서 유지 보수성이 높아진다. (이러한 이유로 크고 복잡한 네트워크도 TCP/IP라는 프로토콜 스택으로 계층화돼있다.) 계층화의 핵심은 한 계층의 모든 요소는 오직 같은 계층에 존재하는 다른 요소 또는 계층상 아래에 위치한 요소에만 의존하는 것이다. 어떤 계층의 상위 계층에 대한 의존, 결합은 최소화 해야한다. 그래야 모듈화의 이점을 볼 수 있다.

DTO는 어디까지 전달하는게 좋을까?

앞서말한 레이어드 아키텍쳐의 장점 때문에 스프링 웹 프로젝트에서 레이어드 아키텍쳐를 적용해봤다. 프론트(뷰)에서 보낸 json 형태의 데이터를 @ResponseBody를 사용해 DTO 객체로 변환하여 컨트롤러에 전달하고, 이 DTO를 그대로 서비스 레이어에 전달해서 비지니스 로직을 구현했다. DTO의 목적은 “계층간 데이터 전달”이므로, 그래도 된다고 생각했었다.

하지만 이렇게 할 경우 문제가 생긴다. 뷰 - 컨트롤러 - 서비스에서 각각 의존이 발생한다. 만약 나중에 기능을 변경해야할 경우 뷰, 컨트롤러, 서비스를 모두 연쇄적으로 수정 해야하는 상황이 발생할 수 있다. 모듈화의 이점을 보려고 레이어드 아키텍쳐를 적용한 것인데, 각 개발 요소에서 종속이 발생하고 있었다. 레이어드 아키텍쳐를 잘못 적용했다고 생각했다.

그래서 내린 내 수준에서의 작은 결론은 "컨트롤러 메서드에서 DTO를 도메인 객체로 변환한 후 서비스 레이어로 넘겨준다."이다. 이렇게 하면 뷰에서 컨트롤러까지 의존하고 있던 서비스를 분리할 수 있다. 즉, 컨트롤러가 뷰로부터 어떤 DTO 형태로 데이터를 전달받더라도 서비스는 상관 없어진다. 더 이상 컨트롤러의 DTO를 사용하지 않고 도메인에 의존하기 때문이다. 이렇게 하면 여러 종류의 컨트롤러에서 서비스를 사용할 수도 있다.

아래 코드를 참고해보자

@Controller
class PostRestController {

   //...

    @PostMapping
    @ResponseStatus(HttpStatus.CREATED)
    @ResponseBody
    public PostDto createPost(@RequestBody PostDto postDto) {
        Post post = convertToEntity(postDto);
        Post postCreated = postService.createPost(post));
        return convertToDto(postCreated);
    }

    @GetMapping(value = "/{id}")
    @ResponseBody
    public PostDto getPost(@PathVariable("id") Long id) {
        return convertToDto(postService.getPostById(id));
    }

    @PutMapping(value = "/{id}")
    @ResponseStatus(HttpStatus.OK)
    public void updatePost(@RequestBody PostDto postDto) {
        Post post = convertToEntity(postDto);
        postService.updatePost(post);
    }
}
// 출처 : https://www.baeldung.com/entity-to-and-from-dto-for-a-java-spring-application

여러 자료를 참고해보니 정답이 없는 문제라고 느꼈다. 지금은 여기까지만 고민하도록 하고 나중에 다시 고민해봐야겠다.

참고

  • https://www.slipp.net/questions/93
  • https://www.slipp.net/questions/23
  • https://os94.tistory.com/157
  • https://wikibook.co.kr/article/layered-architecture/
  • https://wikibook.co.kr/article/layered-architecture/
  • https://velog.io/@ljinsk3/About-DTO-Data-Transfer-Object

태그: ,

카테고리:

업데이트: