1. 문제 정의 — 왜 Node에서는 MapStruct가 안 보일까?

Java/Spring 환경에서는 MapStruct 같은 도구로
Entity ↔ DTO 매핑을 컴파일 타임에 자동 생성할 수 있다.
하지만 Node.js/TypeScript에서는 비슷한 경험을 기대하기 어렵다.
그 이유는 명확하다.

  • TypeScript는 런타임에 타입 정보가 사라진다
  • Annotation Processing 같은 컴파일 타임 코드 생성 구조가 없다
  • 결국 “자동 매핑”을 위한 기반 자체가 부족하다

즉, 같은 문제를 다른 방식으로 풀어야 한다.


2. 접근 방식 전환 — “자동 매핑”이 아니라 “자동 생성”

Node/TS에서의 핵심 전략은 이것이다.

도구로 자동화하지 말고, 생성 프로세스를 자동화하라

즉,

  • MapStruct 같은 라이브러리를 찾는 대신
  • AI(Claude, GPT)를 활용해 DTO와 mapper를 생성한다

3. 실무 표준 구조

다음 구조를 기준으로 잡으면 유지보수성과 확장성이 모두 확보된다.

/domain      → Entity
/dto         → zod 기반 DTO
/mapper      → 변환 함수 (AI 생성)
/controller  → API Layer

4. DTO는 zod로 통합한다

TypeScript에서 DTO는 단순 타입이 아니다.
검증 + 타입 + 계약을 동시에 가져가야 한다.
이 역할을 Zod 하나로 해결할 수 있다.

import { z } from "zod";

export const UserDtoSchema = z.object({
  id: z.number(),
  name: z.string(),
});

export type UserDto = z.infer<typeof UserDtoSchema>;

장점

  • 타입 + validation + runtime schema 통합
  • 프론트/백엔드 공유 가능
  • API contract 명확화

5. Mapper는 단순 함수로 유지한다

Node에서는 “마법 같은 자동 매핑”보다
명시적이고 단순한 함수가 더 강력하다

export const toUserDto = (entity: User): UserDto => ({
  id: entity.id,
  name: entity.name,
});

설계 원칙

  • 비즈니스 로직 금지
  • 1:1 매핑만 수행
  • 테스트 가능하게 유지
  • 사람이 작성하지 않고 AI로 생성

6. AI를 활용한 보일러플레이트 제거

이 구조의 핵심은 AI 활용이다.
다음과 같은 프롬프트를 사용하면 된다.

User 엔티티를 기반으로
zod DTO와 mapper 함수를 생성해줘.

조건:
- zod schema 사용
- z.infer로 타입 생성
- mapper는 순수 함수
- optional/null 안전 처리
- Date → ISO string 변환
- 중첩 객체는 별도 mapper로 분리

이렇게 하면 반복 작업은 사실상 0에 가깝게 줄어든다.


7. 실무에서 중요한 규칙

1) DTO 수동 작성 금지

→ 반드시 생성

2) mapper 수정 금지

→ 변경 시 재생성

3) 변환 규칙 고정

예:

  • snake_case → camelCase
  • Date → string
  • null 처리 정책

이 규칙이 없으면 팀 전체가 무너진다.


8. MSA에서의 확장 전략

이 구조는 단일 서비스뿐 아니라 MSA에서도 그대로 확장된다.
특히 중요한 포인트:

  • Response DTO
  • Event DTO (Kafka 등)

👉 반드시 분리해야 한다
이걸 섞는 순간 서비스 간 결합도가 급격히 증가한다.


9. 결론

Node.js/TypeScript에서는

  • MapStruct 같은 자동 매핑 도구를 찾는 것은 비효율적이다
  • 대신
    • zod로 DTO를 정의하고
    • mapper 함수를 유지하며
    • AI로 생성 자동화를 한다

이 구조가 가장 현실적이고 확장 가능하다.


한 줄 요약

Node에서는 “자동 매핑”이 아니라 “자동 생성 프로세스”를 설계해야 한다

LIST

+ Recent posts