본문 바로가기
기타

DTO에 대해 알아보기

by 유세지 2023. 1. 21.

이번에 사이드 프로젝트를 하면서 nest로 서버를 만들게 되었습니다. 제대로 해보는 백엔드는 처음인지라 낯선 용어들이 많이 등장해서 이해에 어려움을 겪었는데, 이번 기회에 잘 모르는 개념들을 정리해보려 합니다.

 

Nest CLI에서는 개발자의 편의를 위해 CRUD 요청을 처리할 수 있는 CRUD 생성기를 기본으로 제공합니다. 공식문서의 설명을 빌리자면, nest g resource 명령어를 이용하면 모든 NestJS 빌딩 블록(모듈, 서비스, 컨트롤러 클래스)뿐만 아니라 엔티티 클래스, DTO 클래스 및 테스트( .spec) 파일도 생성합니다.

 

$ nest g resource ${domain}

 

 

설명처럼 많은 파일들이 생성되었는데, 그 중 낯선 파일과 용어를 발견하게 되었습니다. 바로 DTO입니다.

 

 

DTO란?

DTO는 Data Transfer Object의 약자로, 데이터 통신을 위한 객체를 의미합니다. 용어의 의미를 보고 처음 든 건 "데이터 통신을 하는데 왜 따로 객체가 필요하지? 데이터를 그대로 넘겨주면 되는게 아닌가?" 라는 생각이었습니다. 이 의문을 풀기 위해선 먼저 통신에 사용되는 데이터가 무엇인지 알아야합니다.

 

예시로 로그인 기능을 구현해야 한다고 가정해보겠습니다. 실제로 유저라는 도메인이 갖고 있는 데이터들은 굉장히 많지만 그 중 로그인 요청과 응답에 필요한 데이터들은 한정적입니다. 로그인에 성공했다고 해서 유저 테이블에 있는 모든 정보를 넘겨줄 필요는 없겠지요. 당연하게도 필요한 정보들만 선별해서 넘겨주는 것이 효율적입니다.

 

만약 매번 데이터 요청마다 모든 정보를 반환해준다면 어떤 문제가 발생할 수 있을까요?

 

아마도 이런 느낌

 

 

캡슐화가 파괴된다

만약 응답으로 모든 정보를 반환해준다면, 받는 쪽에서는 넘어온 데이터를 통해 감추어 둔 내부 필드나 메서드를 알게 됩니다. 이러한 정보들을 많이 알면 알수록 그만큼 끼칠 수 있는 영향력은 커지게 되고, 그에 따라 문제가 발생할 확률은 높아지게 됩니다.

 

위에서 예시로 들었던 로그인 기능이라고 한다면 아래 그림과 같은 경우입니다.

 

 

필요한 정보 vs 받은 정보

 

 

구현하고자 하는 기능이 로그인에 성공했을때 "OO님 환영합니다!" 라는 팝업 메시지를 띄워주는 것이라면, 필요한 정보는 단순히 로그인에 성공한 유저의 nickname 뿐입니다. 그러나 nickname이 포함되는 정보라고 해서 private하게 관리되어야 하는 password와 같은 필드들을 포함한 오른쪽의 모든 데이터를 넘겨주는 것은 적절하지 않습니다. 중간에서 nickname만 따로 전송할 수 있도록 처리해주는 것이 좋습니다.

 

 

책임과 역할이 모호해진다

잘 분리된 역할은 프로젝트의 복잡성을 제어하는데 큰 도움을 줍니다. 그러나 위와 같은 상황이 발생할 경우 분리되어있던 역할은 하나 둘 서로의 영역을 침범하며 모호해지고, 그 책임 또한 여러 곳에서 나누어 갖게 되며 이에 따른 부담은 온전히 프로그래머가 짊어지게 됩니다.

 

역으로 생각하면, 필요한 데이터만 잘 간추려서 반환해주는 것으로 이러한 책임과 역할의 분리나 캡슐화 등의 이점들을 가져갈 수 있습니다. 여기서 "필요한 데이터만 잘 간추려서" 의 역할을 바로 DTO가 해줄 수 있습니다.

 

 

dto를 통해 원하는 데이터만 가져올 수 있습니다

 

 

 

실제로 dto를 제대로 사용하기 전에 작성하는 포스트이다 보니 위에 적은 내용 이외에는 크게 와닿지 않는 느낌입니다. 계속해서 nest를 이용해 개발해보며 느낀 점이 생기면 이 포스트에 추가해나가도록 할 예정입니다.

 

추가적으로 이 글을 작성하며 찾아봤던 많은 자료들이 DTO를 설명하며 VO(Value Object), 엔티티(Entity)와 비교하여 다루는 것을 발견했습니다. 다음에는 이 내용들과 함께 다루어 보겠습니다.

 

 

참고문서

요청과 응답으로 엔티티(Entity) 대신 DTO를 사용하자

DTO의 개념과 사용범위

반응형

댓글