Mobx와 Axios를 이용하여 비동기를 generator 문법으로 사용해본 경험이 있는데,
겪었던 불편함을 정리해보자면 다음과 같습니다.
이와 같은 불편함을 해결하고자 React Query를 채택하여 사용하게되었습니다.
다른 라이브러리들에 비해 국내 포스팅이 모자란다는 느낌이 들긴 하지만
Fetching Status를 바로 할당하여 쓸 수 있다는 점,
스크린이 포커스 될 때마다 데이터를 받아올 수 있다는 점 등이 아주 매력적이었습니다.
(Typescript 혼용에 대한 설명이 조금은 부실하여 리서칭이 더 필요한 상태입니다)
React Query는 보통 훅의 형태로 쓰이게 되는데
이 때 비동기 처리 메소드인 queryFn을 받습니다.
// ex)
const query = useQuery('queryKey', queryFn);
const queryWithTypescript = useQuery<Something, Error>('queryKey', queryFn);
queryFn은 axios(fetch)를 사용하듯 선언하는 메소드였기 때문에
여기서 또 한가지 라이브러리를 채택하기로 했습니다.
ex)
npx swagger-typescript-api -p {SWAGGER_JSON_URL} -o {OUT_DIR}
위 라이브러리는 서버의 swagger.json에 정의된 paths(api, 본문 service),
definitions(model)를 Typescript 파일로 클라이언트에 생성해줍니다.
저는 axios를 사용했기 때문에 --axios true
인자를 추가로 했습니다.
각 프로젝트 성격에 맞게 package.json에 script로 등록을 한다면
API 업데이트에 맞춰 간편하게 Client도 업데이트가 가능하겠죠?
정상적으로 파일이 생성되었다면 아래와 같을 것입니다.
service 모듈에는 swagger에 정의된 getUser ('/user/{userId}')와 같은
메소드들이 선언된 클래스파일들이고,
// ex
const api = new User();
api.getUser(001).then(res => res.data);
// return AxiosResponse<User>
data-contracts는 각 definition의 export interface가 선언된 파일들입니다.
기본적으로 생성된 service들은 http-client의 axios.request를 거쳐갑니다.
이 부분에서 interceptor를 이용한 jwt validation 처리를 할 수도 있고,
공통된 에러를 처리하는 것도 가능합니다.
이제 api와 통신하는 비동기 메소드들도, 쓰고 받아야 하는 model interface도
클라이언트에서 모두 끌어다 사용할 수 있게 되었습니다.
하지만 생성되는 파일들의 완성도를 위해서라면 Swagger 정의를 빡세게 해야겠네요.
자동화 한다는 것이 항상 득과 실이 있는 것 같습니다.
가장 핵심은 과정을 이해하고 있느냐겠죠
언젠가 편하게 사용하던 라이브러리들의 관리가 중지된다면
과감하게 Fork하여 유지보수 할 수 있을 정도로 성장해야겠단 생각이 드네요