TypeScript는 데이터타입에 대한 룰을 적용한다. 백엔드에서 API를 보내주는 데이터 객체 모델링에 대해서 오늘을 얘기해보자. DTO의 설계는 협업에서 매우 중요한 단계이다. URL과 DTO 모델이 어떤 모양의 데이터 객체로 들어오게 할 것인지 먼저 설계를 하고 작업해야한다. 그래야지 서로 물어볼 일도 없을 것이고 시간을 절약할 수 있다. 위의 그림은 NestJs에서 권장하는 객체모형이다.
한 화면에서 보여지는 데이터 값들을 객체화시키고 어떤 타입의 데이터로 받아올 것인지를 정의한다고 생각하면된다.
이전 타입스크립트에 관한 포스팅에서 함수를 용광로를 비유로 든적이 있다. 인터페이스로 틀을 만들고 만들어진 산물이 DTO다.
필자는 NestJS를 이용한 Todoist 프로젝트를 공유하려고한다.
짧은 코드지만 타입스크립트에서 핵심적인 기능인 Interface, enum 그리고 annotation이 담겨져 있다. 여기서 enum이란 개념은 어떤 상황에서 많이 사용할까?
아주 쉬운 예들을 들어보면
실시간 채팅앱에서 로그인 상태이면 초록불이 들어오고 로그아웃인 상태면 파란불이 들어온다. 온라인 오프라인 두 정보 중에 하나만 알면 된다.
언어적인 부분에서도 쓰인다. 우리가 만든 앱이 한국어와 영어만 지원된다면 ko, en과 같은 형식으로 언어에 대한 값의 범위가 정해져있다.
범위 밖의 데이터가 들어가지 않게 하는 장치로 enum을 사용한다고 생각하면된다.
이렇게 우리는 CreateTaskDto란 DTO모델을 만들었다. 그 다음은 service 코드를 살펴보자.
Service에서는 DTO를 어떤식으로 사용할지를 정하는 곳이다. 용광로의 공정과정이라고 생각하면 이해가 빠르다. Todoist를 만들기위해서 우리는 여러개의 Task 를 한 배열에 담아 줄것이다. 프론트에서 map함수를 이용하여 화면에 보여지게 하기위해서다.
createTask함수를 보면 interface로 만들어진 Task라는 틀에 실제로 어떤 데이터 값을 넣을 것인지 정의하는 구간이다. 변수구간에 어떤 타입이 들어갈 것인지 정의되어있고 변수에 나와있지 않은 id, status는 기본값을 설정해준다. 이 코드를 만드는 과정에 있어서 개발자가 실수로 잘못된 타입의 데이터를 넣었다면 TypeScript에서는 오류를 알려주고 가이드라인을 제시한다. 여러 파일을 오가야되는 개발자 입장에서는 너무나 든든한 조력자 역할을 해준다. 다음은 공정과정으로 나온 산출물이 어떻게 나오게 할 것인지 정의해주는 컨트롤러 파일을 살펴보자.
컨트롤러 파일에서는 서비스에서 정의한 공정과정들을 어떻게 써서 어떤 결과를 만들어낼 것인지를 정의한다. 용광로에서 만드는 무기가 완성되는 부분이다. getAllTask라는 함수는 서비스에서 정의한 getAllTask란 함수를 사용하여 Task로 만들어진 배열의 결과값으로 나올 것이고 createTask에서는 Body에 title값과 description 값을 넣어 서비스에 있는 createTask 함수를 실행시킬 것이다.
프론트개발자와 백엔드개발자 사이에는 제로썸 게임이 존재한다. 각 화면마다 API를 쪼개서 줄 것인지 그냥 통으로 API를 줄 것인지 프론트 개발자는 API가 크게 들어올 수록 연결과정에서 큰 혼란을 느끼게 된다. 백엔드개발자는 API를 쪼개서 보내면 일이 많아진다. 이를 해결하기 위해서 DTO설계를 통해 명백한 기준을 만들고 그 기준을 참고로 작업을 한다면 이직이 많은 IT분야에서 효율적인 협업을 위한 유연한 대처라고 필자는 생각한다. 협업으로 효율을 낼지 비효율을 낼지는 명백한 기준의 유무에 따라 결정된다.
다음 NestJS 관련 포스팅에서는 GraphQL과 mongodb데이터 베이스를 이용한 NestJS활용법에 대해 다뤄보겠다.