Swagger 문서에 정의된 DTO 코드 자동 생성하기
서론
이 글은 TypeScript와 Swagger를 사용하는 프로젝트 사례를 소개합니다.
REST API를 사용하기 전에 Swagger 문서를 보고 DTO 파일을 정의하곤 합니다. 수동으로 DTO 파일을 작성 가능하지만 오픈 소스를 활용해서 자동화하면 별도로 코딩 룰을 정의할 필요 없고, DTO가 변경되었을 때 쉽게 변경할 수 있습니다.
이 글을 통해서 Swagger 문서에 정의된 DTO를 자동으로 생성하는 방법과 큰 규모 프로젝트에서 개발 생산성을 위해 라우팅 파일을 번들링 하는 방법을 소개합니다.
Swagger 문서에 정의된 DTO 자동 생성
Swagger 문서의 DTO는 swagger-typescript-api
를 사용하면 자동으로 프로젝트의 TypeScript 파일로 생성할 수 있습니다. 도입 초기에는 DTO를 단일 파일로 관리해서 Git diff가 많아지고 추가/수정된 DTO를 파악하기 힘들었습니다.
옵션을 적절하게 사용하면 파일을 분리해서 쉽게 관리할 수 있습니다. 프로젝트에서 사용할 때 package.json
에 정의해서 사용했는데, 명령어와 옵션을 다음과 같습니다.
swagger-typescript-api -p {Swagger JSON 주소} -o {DTO 파일 경로} --no-client --route-types --modular --sort-types
-p
는 swagger의 json 파일 주소를 설정합니다.-o
는 프로젝트 내에서 swagger DTO 파일을 저장할 위치를 설정합니다.--no-client
는 오픈 소스를 실행하면 API를 요청하는 JS 코드가 생성되는 데 이를 방지합니다.--route-types
는 API 라우트 경로를 각각 namespace를 분리해서 정의합니다.--modular
는 DTO 중에서 API 라우트에서 공통으로 사용하는 파일을data-contracts.ts
파일로 분리할지 설정합니다.--sort-types
는 DTO를 정렬해서 정의합니다.
라우트 파일 번들링
현업에서는 서비스 기능마다 REST API가 다르기도 하는데, 각 기능마다 프런트엔드 담당자가 다르기도 합니다. 동료들과 같은 저장소를 사용하는 상황에서 공통 DTO 파일은 저장소 파일에서 충돌 문제가 발생되곤 합니다. 때문에 코드 머지를 하거나 Pull Request에서 충돌 문제를 수동으로 해결하는 경우가 발생합니다.
이 문제를 해결하기 위해 dts-bundle-generator
를 사용해서 DTO 파일을 번들링합니다. 번들링은 아래와 같이 동작합니다.
// route.ts
import { CommonProps, CommonName } from "./common";
export interface Props extends CommonProps {
url: string;
name: CommonName
}
// common.ts
export interface CommonProps {
description: string;
}
export type CommonName = string;
위 파일이 있을 때 dts-bundle-generator -o bundle.d.ts ./route.ts
명령어를 실행하면 아래와 같이 번들링된 파일이 생성됩니다.
// Generated by dts-bundle-generator v8.0.1
export interface CommonProps {
description: string;
}
export type CommonName = string;
export interface Props extends CommonProps {
url: string;
name: CommonName;
}
export {};
마치며
마지막으로 오픈 소스를 활용해서 생성된 TypeScript 코드는 프로젝트의 코딩룰과 다를 수 있습니다. 이 문제는 Swagger의 DTO 파일을 자동으로 생성할 때, 현재 프로젝트의 설정된 eslint 또는 prettier 를 사용하면 쉽게 해결할 수 있습니다.