
API Client Generator란 서버에서 작성한 API 명세(OpenAPI, Swagger 등)를 기반으로 클라이언트에서 필요한 코드(함수, 타입 등)를 자동으로 생성해주는 도구를 말합니다.
이번 프로젝트는 제공된 서버 API를 기반으로 작업을 해야했고, API 명세는 Swagger UI 형태로 제공되었습니다. API Client Generator를 사용하려면 json 또는 yaml 형식의 명세 파일이 필요했습니다.
일반적으로 명세 파일은 Swagger 페이지에서 관련 URL 링크를 통해 다운로드하거나 특정 endpoint를 통해 확인할 수 있습니다.

처음에는 위와 같은 방식으로 명세 파일을 찾으려고 시도했지만, 별도의 다운로드 경로나 파일이 명시적으로 제공되지는 않았습니다. 또한 Network 탭을 통해서도 원하는 파일은 발견할 수 없었습니다.
이후, 브라우저에 로드되는 JavaScript 파일들을 하나씩 살펴보던 중, 내부 변수에 OpenAPI 명세와 유사한 구조로 작성된 데이터를 발견할 수 있었습니다. 이는 공식 명세 파일은 아니었지만, 타입 자동화 작업에 충분히 활용 가능하다고 판단했습니다.
추후 서버 측에 직접 요청하여 제공받은 명세파일과 확보한 데이터를 비교한 결과, 구조가 동일함을 확인할 수 있었습니다.
[ 직접 추출한 명세 데이터 ]

// 설치하기
npm install swagger-typescript-api -D
// 실행하기
npx swagger-typescript-api -p ./swagger.json -o ./src/swagger --modular --axios
생성된 파일들
data-contracts.ts: 서버 타입 정의 파일http-client.ts: axios 설정 파일TeamId.ts: API 요청 함수 파일
data-contracts.ts

TeamId.ts
HttpClient를 확장하여 API 요청 함수 생성
npx swagger-typescript-api -h 명령어를 통해 다양한 옵션을 확인할 수 있습니다.
현재 프로젝트에서는 모든 API 경로가 /{teamId}로 시작했기 때문에, --modular 옵션을 적용했을 때 TeamId.ts로 모든 API 요청 함수가 합쳐졌습니다.
이를 해결하기 위해 --module-name-first-tag 옵션을 추가할 수 있습니다.
npx swagger-typescript-api -p ./swagger.json -o ./src/swagger --modular --module-name-first-tag --axios
--module-name-first-tag 옵션 적용 시, Swagger 명세에 설정된 tags의 첫 번째 값을 기준으로 API 요청 파일이 분리됩니다.
// 설치하기
npm install @openapitools/openapi-generator-cli -D
// 실행하기
npx @openapitools/openapi-generator-cli generate -i ./swagger.json -g typescript-axios -o ./generator
typescript-axios)생성된 파일들

주요 파일
base.ts, common.ts 등: API 요청 함수 생성을 위한 공통 함수 및 환경 설정 파일api.ts: 서버 타입과 API 요청 함수가 함께 정의된 파일api.ts 파일 내용


처음에 명령어를 실행했을 때, 아래 이미지와 같은 오류가 발생했습니다.

이런 문제가 발생하지 않도록 서버 측에서도 API 명세 작성을 꼼꼼히 관리해야한다는 것을 느꼈습니다.
처음 추천받았던 라이브러리는 openapi-generator였습니다. 또한, 구글링을 통해 openapi-generator가 많이 사용되고 있다는 것도 확인할 수 있었습니다.
프로젝트는 Axios와 Typescript를 기반으로 진행되었는데, 추가로 정보를 찾아보던 중 swagger-typescript-api를 알게 되었고, 생성되는 결과물이 조금 더 간결하고 프로젝트에 적용하기에도 적합할 것 같아 먼저 시도해보게 되었습니다.
swagger-typescript-api를 통해 Axios 설정파일, API 요청 함수 파일, 타입 파일을 생성하고 활용 방안을 검토하던 중, 서버로부터 공식 명세 파일을 전달받게 되었고, 다른 팀원이 기존에 추천받은 openapi-generator를 이용해보았습니다.
openapi-generator는 swagger-typescript-api와 비교해 생성되는 주요 파일 구조는 비슷했지만, .npmignore, .gitignore, git-push.sh와 같은 추가 파일들도 함께 생성되었습니다.
결과적으로 저희는 타입 파일만을 사용하는 방향으로 결정하면서, 조금 더 세세한 타입을 얻었던 openapi-generator의 결과물을 최종적으로 적용했습니다.
참고로, swagger-typescript-api도 명령어 옵션을 조정하여 더 자세한 타입 생성을 지원하지만, 이미 확보한 openapi-generator 결과물로도 프로젝트에 사용하기에 적절하다는 판단으로 추가 작업 없이 그대로 사용했습니다.
서버 타입이 자동으로 생성되어 바로 사용할 수 있다는 점은 개발 생산성 측면에서 매우 만족스러웠습니다.
다만 경험하면서 느낀 점은, 서버 측 명세가 잘 작성되지 않으면 생성된 타입명이 혼란스러워질 수 있다는 것이었습니다. 특히 복잡한 API 구조를 가진 경우, 명세가 꼼꼼히 작성되어야 혼란을 방지할 수 있을 것이라는 생각이 들었습니다.
참고로, 이 도구를 추천해주신 분은 서버 타입은 openapi-generator로 자동 생성하고, 클라이언트에서 필요한 타입은 별도로 작성한 뒤, 추상화 함수를 통해 서버 타입을 클라이언트 타입으로 변환하는 방식을 사용한다고 알려주셨습니다.
처음에는 "타입 변환 자동화"가 목적이라면 추가 추상화 작업이 왜 필요한지 의문을 가졌습니다. 그러나 앱 환경 기반으로 말씀해주신 점을 고려해, 배포 심사를 거쳐야 하고 디버깅이 상대적으로 쉽지 않다는 점을 고려했을 때, 서버 데이터에 문제가 생기더라도 추상화 함수를 통해 빠르게 디버깅하고 문제를 최소화할 수 있다는 장점이 있다는 것을 이해하게 되었습니다.
반면 웹 환경에서는 상대적으로 배포가 자유롭고 디버깅이 용이하기 때문에, 무조건 추상화 작업을 적용하는 것보다는 타입을 꼼꼼하고 엄격하게 관리하고 싶고, 시간적 여유가 있을 때 적용하는 것이 더 적절하겠다는 생각을 했습니다.
타입명이 혼란스럽게 생성된 부분에 대해서 팀원들과 논의 과정을 거쳤습니다.
타입명을 직접 수정하여 깔끔하게 정리하는 방안도 고려했지만, 최종적으로 수정하지 않고 그대로 사용하는 방향으로 결정했습니다. 그 이유는, 타입명을 일일이 확인하고 수정하는 과정이 이 도구를 사용하는 본래 목적(자동화의 이점)에 어긋난다는 점, 그리고 실무에서 API 명세가 변경될 때마다 수동으로 타입명을 다시 수정하는 것은 현실적으로 어렵다는 판단 때문이었습니다.
하지만 회고해보니, 자동 생성된 임시 타입명에도 일정한 패턴이 존재했기 때문에, 이를 기반으로 스크립트를 작성해 일괄적으로 깔끔한 타입명으로 변환하는 방법도 충분히 고려해볼 수 있었겠다는 아쉬움이 남았습니다.
또한, 이번에는 생성된 API 요청 함수를 별도로 사용하지 않았지만, 미리 작성해둔 Axios 인스턴스와 함께 적절히 가공하여 사용했다면, API 호출 부분에서도 생산성을 더 높일 수 있었을 것이라는 생각이 들었습니다.
Swagger 타입 자동 생성기 적용기
OpenAPI Generator로 API의 안전한 Model과 정형화된 구현코드 자동생성하기
추가적으로, 팀원이 작성한 글(OAS Generator 사용해보기)을 통해 openapi-generator 도입 과정을 자세히 확인할 수 있습니다.