프로젝트에 처음 타입스크립트를 도입을 결정하게 되었던 것은 API 때문이었다.

백엔드 서버가 웹 프로젝트가 없는 시점부터 만들어져서 많은 부분에 앱에 맞춰져 있다.

예를 들면 웹에서의 페이지네이션을 지원하기 위해서는 서버에서 데이터의 총 개수를 알려주어야만 총 몇 페이지인지 알 수 있어서 기존에 없던 정보를 추가했어야 했지만, 앱의 경우 이전 버전의 호환성을 유지해야 하므로, 기존에 배열로 전달해주고 있던 데이터의 형태를 바꾸지 않고 총 개수를 전달해주기 위해선 HTTP header에 값을 전달해주는 수 밖에 없었다.

하지만 모든 API가 그런 것은 아니고 일부 API만 그러해서 http client로 사용하고 있는 객체에서는 header에 총 개수가 담겨있는지 여부에 따라 분기를 처리해주도록 클라이언트에서 처리가 되어있었다.

또한 사용하고 있는 API 중에서도 문서가 지원되지 않아 Postman으로 요청해보거나 프로젝트에서 사용되고 있는 코드를 보고 추론하는 식의 접근을 해야 했다.

마지막으로 서버도 점차 발전해나간 부분이 있어서 만들어진 시점에 따라 조금씩 다른 형태로 진화해나가면서 지금의 통일된 포맷이 아닌 API들이 조금은 혼재되어있었다.

이런 지점들이 기존 컨텍스트에 익숙한 사람이 아니라면 어려움이 있었고, 어떤 API를 사용해야 할 때 위와 같은 지점들을 매번 겪는 것은 좋지 않다고 생각하여 고민하게 되었다.

그래서 개별 API별로 대응되는 API를 만들고, 주석이 아닌 코드로서 요청과 응답 데이터 형식을 나타내기 위해 타입스크립트를 사용하는 것이 좋겠다고 판단을 내렸다.

위 함수들을 어떻게 파일관리를 하는 것이 좋을지도 고민대상이었는데, 누가 봐도 해당 API에 대응하는 함수가 무엇인지 찾을 수 있도록 API url 주소에서 /__ 로 변환하여 폴더 구조를 만들어 제일 하단부에 HTTP Method명을 파일명으로 해서 함수를 보관하도록 하였고, 모든 함수는 api/index에서 export * from "" 을 거치도록 해서 사용처에서는 import * as api from "api"; 와 같이 쓸 수 있도록 하였다.

import { fetcher } from "utils";

import { GetTestResponse, IPage } from "typings";

type GetTest = (params: { id?: number | string; page: IPage }) => Promise<GetTestResponse>;

export const get__test: GetTest = params => fetcher.get("/test", params);