OpenAPI 문서에서 TypeScript 타입 만들기

OpenAPI 문서를 통해 TypeScript 타입 정의를 생성하는 스크립트 만들기

남현욱
None
6 min readMar 18, 2021

--

휴먼스케이프 소프트웨어 엔지니어 Henry입니다 :)

이번 포스트에서는 npm 패키지 openapi-typescript-codegen을 활용하여 OpenAPI 스펙 문서를 기반으로 TypeScript 타입을 생성하는 방법을 알려드리려고 합니다.

개요

프론트엔드 개발을 TypeScript로 진행하시는, 혹은 해보셨던 분들이라면 백엔드 API의 응답에 대해서 타입을 지정해봤던 경험이 한 번쯤 있으셨을 것입니다. 아마 팀의 형태와 개발하는 방식에 따라서, 직접 코드를 작성하는 경우도 있고 Generator의 힘을 빌려 작성하는 경우도 있습니다.

프론트엔드와 백엔드 모두 TypeScript로 코드를 작성하게 된다면, DRY 원칙에 입각해서 이 문제에 대해 일찌감치 고민하게 됩니다. (같은 타입을 같은 언어로 두 번이나 정의한다고?!)
그래서 엔티티 레벨의 타입 정의를 분리해서 설치할 수 있는 형태로 패키지화하거나, 모노레포를 구축하여 사용하기도 합니다.

그런데, 백엔드는 Python으로 이루어져 있고 프론트엔드는 TypeScript로 이루어져 있는 경우에는 어떻게 할까요? 언뜻 보면 하나의 엔티티는 같은 개념을 가지고 있지만 눈물을 머금고 서로 다른 언어로 두 번 정의하게 됩니다.

또 프로젝트를 JavaScript에서 TypeScript로 점진적으로 전환하는 경우에도 문제가 발생합니다. 이렇게나 많은 코드에 하나하나 타입을 매길 수 있을 지, 하려면 얼마나 걸릴 지 막막함부터 앞서게 되고, 기간이 오래 걸리고 우선순위에 밀리면서 결국 숙원사업의 형태로 남게 되는 것이 일반적입니다. 😭

그렇지만.. 타입은 지정해주고 싶어요!

아무리 어렵고 고되다고 한들 API 응답의 타입을 하나같이 Promise<any>로 떡칠할 수는 없었습니다. 그럼 무조건 TypeScript로 백엔드를 개발해야 할까요? 그렇지 않으면 API 응답 타입은 무조건 하나하나 지정해줘야 하는 것일까요? 🤔

어떻게 보면 틀린 방법은 아닌 것 같습니다. 그러나 개발자는 타입 지정보다 더 재밌는 일들을 하고 싶어하기 때문에 이 부분에 조금 더 시간을 적게 들이고 싶을 것입니다.

그러다 문득 graphql-code-generator 라는 프로젝트를 떠올렸습니다. 이 프로젝트는 GraphQL 스키마의 정적 분석을 통해, 지원되는 언어의 모델을 1:1로 변환해주는 프로젝트입니다. GraphQL의 특성을 고려하여, 같은 코드를 두 번 쓰지 않으려는 노력의 일환이라고 생각합니다.

위 프로젝트를 보고, 스키마의 정적 분석이 가능하다면 대응되는 코드는 얼마든지 변환할 수 있다는 생각이 들었습니다. 그럼 REST API는 무엇을 통해 정적 분석을 할 수 있을까요? 바로 OAS(OpenAPI Specification) 입니다.

OAS의 예시 문서를 확인해보시면 눈에 띄는 특징이 있는데, 모든 API의 명세가 나와있습니다. 이 정보로 정적 분석을 함으로써 우리가 원하는 타입 정의를 생성할 수 있습니다.

스크립트 작성

위에도 언급했듯, 이런 일을 해주는 npm 패키지 openapi-typescript-codegen 을 사용하여 OAS를 타입 정의로 만들어주는 간단한 스크립트를 작성해보겠습니다.

Node.js v14 환경에서 작업 및 테스트를 진행했습니다.

먼저 빈 프로젝트를 만들고, 아래 명령어를 콘솔에 입력합니다.

이후 package.json의 scripts 부분을 생성하여 아래와 같이 만들어둡니다.

그 후 scripts 폴더에 generate-openapi-types.js 파일을 생성하고, 아래 코드를 작성한 후 아까 작성해둔 스크립트로 잘 작동하는지 확인해봅니다.

문제없이 잘 작동하는 것을 확인했으니, 간단한 프로그램을 작성해봅시다.

OAS 문서를 다운로드하여 저장한 후, 해당 문서로 Codegen을 진행하는 간단한 프로그램입니다. 이제 이 프로그램을 돌려보면 아래와 같은 결과가 나오게 됩니다.

우리가 원하던 타입 정의가 자동으로 생성되었습니다! services 디렉토리에는 간단한 서비스 구현까지 해놓은 모습이 보이네요 :)

작성한 코드를 정리하여 GitHub 레포지토리에 올려두었습니다.

정리

개요에서 설명드렸듯, 타입을 하나하나 작성하기가 어렵거나 같은 일을 두 번 하는 것에 두려움이 있어 백엔드 API 응답의 타입 작성이 꺼려지셨던 분들을 위한 라이브러리를 소개했습니다.

그러나 소프트웨어 엔지니어링의 세계에 은탄환은 없습니다. 타입을 정의할 리소스가 충분해서 하나하나 타입을 작성할 수도 있고, 엔티티는 타입이 공유되어야 한다는 원칙을 세워 그 원칙에 맞게 프로젝트를 구성할 수도 있습니다.

이 글을 통해 API 응답 타입을 정의하려는 분들이 좋은 인사이트를 얻었으면 하는 바램입니다. 감사합니다 🤗

--

--

남현욱
None

세상이 아름다워지는 것을 지향하는 프론트엔드 개발자 남현욱입니다. 휴먼스케이프에서 프론트엔드 개발을 하고 있습니다.