일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 | 29 |
30 | 31 |
- gql restapi 차이
- v8 원리
- 렌더링 최적화
- 항해99 부트캠프
- jwt
- 타입스크립트
- 함수형 프로그래밍 특징
- 리액트 메모이제이션
- 알고리즘
- 항해99
- Js module
- 자바스크립트 엔진 v8
- next js
- toggle-btn
- 코어자바스크립트
- 리덕스
- 실행컨텍스트
- chromatic error
- this
- 웹 크롤링
- 리액트
- 항해99 미니프로젝트
- JS module system
- 리액트 렌더링 최적화
- 테스트 코드 툴 비교
- 리액트 메모
- FP 특징
- 항해99 사전스터디
- js배열 알고리즘
- 웹팩 기본개념
- Today
- Total
Jaeilit
swagger-typescript-api 도입 후 fetchUtils 마이그레이션 본문
도입배경
서버개발을 시작하면서 API를 처음 설계하다보니 설계방식에 문제가 있었습니다. RESTfull 하게 작성하려고 더 나은 방식을 찾을 때마다 설계를 수정하게 되었고 도화지 위에서 그림을 그렸다 지웠다하는 식의 일이 반복적으로 발생했고 그로인해 개발의 속도가 나지않고 계속 제자리 걸음을 하는 듯한 느낌이 들었습니다.
느리지만 단단하게.. 가려고 했습니다. 누구나 처음에는 서툴지만, 잘해보이기 위해 능숙한척 하는 것보다 포인트를 정확히 짚고 넘어가면서 익숙해지면 자연스레 능숙함은 따라온다는 내 삶의 철학이 녹아있었기 때문이었습니다.
하지만 이런 서버의 API의 잦은 변경의 부하들은 클라이언트에서 다 받게 되었습니다.
- API 엔드포인트 변경
- 요청/응답 body, parameter 구조 변경
- 타입 불일치로 인한 런타임 에러
- 잘못된 API 호출로 인한 예외 케이스, 에러
물론 데브서버라서 큰 문제가 되지 않았지만, 만약에 운영단계라면 기능적 오류로 인해 에러 메세지나 에러 페이지가 노출 될 수 있습니다. 이건 사용자 경험에 직접적인 영향을 미치는 심각한 문제라고 생각했습니다.
백엔드의 API 문서를 클라이언트와 동기화하여 사용 할 수 없을까?
사실 이전에 회사에서 gql을 사용할때는 gql-codegen이라는 gql 백엔드 스키마를 typescript로 변환해주는 유틸리티 툴을 도입을 해서 잘 사용했기 때문에 그 편리함을 다시 누릴 수 있지 않을까 생각해서 찾아보게되었습니다.
swagger-typescript-api 도입
npm trends를 통해 조사해본 결과, API 코드 생성 도구들 중 가장 많이 사용되는 두 가지 라이브러리를 발견했습니다
- swagger-typescript-api
- openapi-typescript
두 라이브러리를 비교 분석하며 다음 사항들을 고려했습니다
현재 개발 환경과의 호환성
- 이미 Swagger로 API 문서화를 하고 있어, swagger-typescript-api가 더 도입이 쉬울거라고 판단
- 문서화가 잘 되어있어 도입이 상대적으로 용이 (러닝커브가 없을거라고 판단)
결론적으로, 이미 Swagger로 문서화 된 API를 기반으로 타입을 생성하는 것이 러닝커브도 없을 것이고 더 자연스럽다고 느껴져서 swagger-typescript-api 도입을 결정했습니다.
swagger-typescript-api 설정 중 발생한 문제
swagger-typescript-api -p [SWAGGER_JSON_PATH] -o ./src/api/generated --modular
주요 옵션들
- -p: Swagger JSON 파일 경로 또는 URL
- -o: 생성된 파일이 저장될 출력 경로
- --modular: 모듈 방식으로 코드 생성
사용방법은 간단합니다. -p = path로 백엔드 swagger json 경로를 입력해주거나 json 파일로 추출한 경우 그 경로를 입력해주면 되는데, 저는 여기서 문제가 발생했습니다. json 파일로 추출하는 건 이것 또한 수동작업이라 매번 할 수 없다 판단해서 url 으로 입력하려고 했는데 json 이 있는 경로를 찾지 못했습니다. 하루종일 구글에 swagger-typescript-api 사용법이나 예제를 찾아봤지만 어디에도 json 경로를 알려주는 곳이 없었는데 nestjs 공식문서 open api 에서 답을 찾을 수 있었습니다.
기본 경로는 /api-json 이고 다른 경로로 사용하고 싶으면 url을 지정해서 사용할 수 있다.
swagger/json 경로에서 드디어 문서화 해둔 json을 만날 수 있었다.
클라이언트에서 사용하기
스크립트 명령어에 moduler 옵션을 켜놨기 때문에 저는 파일이 모듈단위로 분리가 되어있습니다 data-contract.ts와 http-client.ts는 기본적으로 들어가는 http 통신을 위한 코드 베이스이고 fetch utils 정도라고 봐도 될 것 같습니다
moduler 옵션을 켜지 않는다면 스크립트 명령어에서 작성한 파일명(기본은 Api.ts)으로 하나의 파일에 모두 작성 될 것 입니다. 하나의 파일에 수천만줄의 코드가 들어가면 아무리 안봐도 되는 코드라고해도 거부감이 드는건 사실이기 때문에 저는 분리했습니다.
분리기준은 추측컨데 controller.ts 에 swagger 에서 불러온 ApiTags('') 이 부분인것 같네요 swageer에서도 이 기준으로 나누니깐요
기존 코드에서 적용 후 코드
적용하고 나서보니 data의 타입추론도 되고 데이터도 잘 받아와지는 것을 확인했고 기존보다 타입 안전성이 향상 됐다고 볼 수 있습니다.
fetchUtils 마이그레이션
기존에는 커스텀 fetchUtils를 사용하여 API 통신을 처리했습니다:
swagger-typescript-api fetching 함수를 사용하려면 해당 API모듈 인스턴스를 초기화 시킨 후에 baseUrl을 기입해줘야하기 때문에 apis를 그대로 사용할 수 없어서 조금 변경이 필요했습니다.
- 싱글톤 패턴 적용
- 불필요한 인스턴스 재생성 방지
- 메모리 사용 최적화
- 타입 안정성 강화
- Swagger 스펙에서 자동 생성된 타입 활용
- API 응답 타입 자동 추론
// 변경 전
const userData = await apis.get<UserType>('/users/1');
// 변경 후
const userData = await api().store.storeControllerGetStore();
이점
- 타입 안정성 향상
- API 문서와 클라이언트 코드의 자동 동기화
- 개발 생산성 향상
- 런타임 에러 감소
이러한 변경으로 API 통신의 타입 안정성이 크게 향상되었으며, 백엔드 API 변경사항을 자동으로 클라이언트에 반영할 수 있게 되었습니다.
'로또헌터' 카테고리의 다른 글
AWS S3를 활용한 프로필 이미지 업로드 구현하기 (0) | 2025.02.21 |
---|---|
DNS를 Route 53에서 Cloudflare로 이전하면서 디도스 방어하기 (0) | 2025.01.20 |
내 사이트 더 많이 노출 시키기(SEO) (0) | 2025.01.16 |