본문 바로가기
Typescript

DTO와 Entity, 이 둘은 무엇이고 어떤 차이점이 있을까?

by shinbian11 2022. 10. 2.

회사에 입사하여 정신없이 9월을 보냈다. 회사에 기여한 것은 별로 없지만, 아무튼 바빴다 ㅋㅋㅋ

 

개인적으로는 첫 자취생활이라 준비할 것이 많았고, 회사생활도 너무나도 새로웠다.

 

여러모로 시간이 너무나도 빠르게 지나간 탓에 블로깅 활동이 너무 뜸했다.

 

그래서 3일의 휴일을 이용하여 재빠르게 생존신고를 하려고 한다.

 


입사 직후, 온보딩의 목적으로 몇 가지의 구현 과제들을 수행하며 몇 번의 어려움을 겪었다.

 

첫째로, 맥북을 처음 써봤다 ㅋㅋㅋ  평생 윈도우만 쓰던 나에게 MacOS 운영체제와 맥북은 다루기 어려운 존재였다.

맨날 쓰던 한영키 위치부터, 커맨드 키 사용의 낯섬 등등.. 

단축키를 포함하여 기존의 윈도우 운영체제와 지금의 MacOS는 다른 부분이 너무 많아 앞으로도 계속 적응해야 할 것 같다.

물론 적응만 한다면 예전보다 훨씬 개발의 질이 높아질 것 같다는 생각이 들었다.

 

두번째로, 프론트엔드 관련 프로젝트만 수행해본 나로써는 프론트엔드와 백엔드의 업무를 동시에 진행하며 부침을 겪었다.

 

세번째로, 회사 자체에서 개발한 프론트엔드/백엔드 프레임워크를 사용했는데, 그것들의 구조와 문법에 익숙해지는데 시간이 걸렸다.

 


 

이러한 어려움을 겪으며 온보딩 과제 구현을 모두 마쳤고, 그 과정에서 학습한 내용들을 선별하여 정리하려고 한다.

 

이번 글에서는, DTO와 Entity는 무엇이며, 어떤 차이점이 있는지 간략하게 정리하려고 한다.

 


 

온보딩 과제의 스켈레톤 코드를 분석하며 생긴 의문점 중 하나는, DTO Entity의 생김새가 매우 비슷했다는 점이었다.

 

그렇기 때문에 이러한 질문이 생겼다.

 

생김새가 비슷한데 굳이 왜 둘로 분리를 할까?

 

궁금증을 해결하기 위해 구글링을 하였는데, 그 과정에서 추가적인 궁금증이 또 생겼다.

 

통신시 모든 계층에서 DTO 주고 받는 경우도 있다고 하는데, 그렇다면 비슷하게 생긴 Entity는 더욱 더 필요성이 없어지는 게 아닐까?

 


 

결론부터 정리하자면 이러하다.

 

- DTO 계층간의 데이터 교환   사용되는 객체이다.

 

- Entity 실제 데이터베이스 테이블(스키마)의 컬럼들과 매핑되는 클래스이며, 데이터베이스의 Row(행)라고 이해해도 거의 무방하다. 

 

 

위의 DTO에서 언급한 계층간의 데이터 교환라는 것은,

 

  • 프론트 계층과 백 계층 사이에서 데이터를 교환할 때
  • 백엔드 내부에서의 controller layer - service layer - model layer 사이에서 데이터를 주고 받을 때

 

모두 해당이 된다.

 


 

예를 들어, 데이터베이스에 유저의 정보를 저장하는 스키마가 있다고 가정하자.

 

로그인 정보를 저장하는 스키마의 컬럼들은 회원의 아이디, 이메일, 이름, 비밀번호, 전화번호와 같은 정보들이 저장될 수 있다.

 

그리고 이 컬럼들의 정보는 아래처럼 객체의 형태로 저장되어 통신할 때 사용된다.

 

class User {
  id: bigint;
  email : string;
  name : string;
  password : string;
  phone : string;
}

 

그 중에서 유저의 비밀번호 같은 민감정보는 백엔드 내부에서는 어떠한 로직들을 수행하기 위해 사용될 수는 있어도, 백엔드에서 프론트로 응답 데이터를 보낼 때 굳이 같이 끼워넣어서 보낼 필요는 없다.

 

프론트엔드쪽으로 가져와도 비밀번호라는 그 정보를 굳이 화면에서 내보일 일이 없기 때문이다.

또한, 운이 없다면 프론트로 응답 데이터를 보내는 도중 누군가에 의해 가로채기를 당해 비밀번호가 노출될 수도 있다.

 

 

참고로, 위에서 언급한 백엔드 내부에서의 어떠한 로직들이란 무엇일까??

회원가입 시 입력된 비밀번호의 유효성을 검사하거나, 그 비밀번호를 암호화해서 데이터베이스에 저장하는 행위들이 예시가 될 수 있다.

 

 

 

어쨌든....

 

 

그래서, 프론트로 응답 결과를 반환할 때 필요한 데이터들의 구성과,

백엔드 내부에서 로직을 처리하기 위해 필요한 데이터들의 구성이 조금 다를 수 있다.

 

이런 경우에, 프론트로 응답 결과를 반환하기 위해 필요한 데이터들은 DTO로,

백엔드 내부에서 로직을 처리하기 위해 필요한 데이터들은 Entity로 정리할 수 있다.

 

 

백엔드 내부에서 로직을 처리할 때 사용되는 데이터들은 최대한 데이터베이스의 컬럼들과 일치하는 것이 좋다.

그래서 Entity의 컬럼들은 데이터베이스의 컬럼들과 매핑이 된다. 외부로 노출되면 안되는 데이터베이스 내의 컬럼들도 가질 수 있다.

 

하지만 DTO는 그렇지 않다.

 

앞서 봤듯이 비밀번호와 같은 정보들은 Entity에는 존재할  있어도 DTO 존재하는 것은 어울리지 않을 수 있다. 

 

DTO는 Entity 컬럼들 중에 민감한 정보를 제외하고, 네트워크 통신을   프론트엔드에서 필요한 데이터들 위주로만 새롭게 구성할  있다. 그러다보니 DTO 내부의 수정은 상대적으로 자유롭다.

 

그렇기 때문에 DTO와 Entity는 분리가 되는 것이다.

 


 

그렇다면 온보딩 도중 보았던 스켈레톤 코드에서 이 둘의 생김새는 왜 비슷했던 것일까?

 

온보딩 과제들은 실제 런칭중인 자사의 서비스와 비교해서 규모가 매우 작은 간단한 업무들이었기 때문이다.

예를 들면 유저 회원가입/로그인/로그아웃 & 댓글과 게시글 CRUD API 설계 등과 같은 것들이었다.

 

기능이 복잡하거나 규모가 큰 업무는, 상황에 따라 프론트엔드에서 보여줘야 하는 데이터의 종류가 다양할 수 있다. 

그러므로 DTO의 구성을 다양하게 변화시켜야 하는 경우도 많다.

 

하지만 온보딩 도중의 업무들은 굳이 그럴 필요가 없었기 때문에, 당연하게도 DTO와 Entity의 생김새 역시 거의 동일했던 것이다.

 

그랬었기 때문에 내가 이러한 의문점을 초반에 가졌던 것 같다.

 


 

결론적으로,

 

Entity는 데이터베이스 테이블(스키마)의 컬럼들과 매핑되는 객체로, 백엔드 내의 layer들 사이에서 데이터를 교환할 때 주로 사용되고,

 

DTO는 백엔드에서 비즈니스 로직을 모두 처리한 이후, Entity에서 필요한 데이터들만 선택적으로 구성하여 프론트엔드에 응답값을 넘겨줄 때 주로 사용되는 객체이다.