-
Notifications
You must be signed in to change notification settings - Fork 1
API 스펙 동기화 및 프론트엔드 API 연동 가이드
김수빈 edited this page Dec 1, 2024
·
4 revisions
이 가이드는 Swagger 문서를 기반으로 타입 안전한 프론트엔드 API 연동 환경을 구축하는 방법을 설명합니다. OpenAPI Generator, React Query, MSW를 활용하여 효율적이고 안정적인 개발 환경을 구성하는 과정을 다룹니다.
- OpenAPI Generator: API 타입과 클라이언트 코드 자동 생성
- React Query: 서버 상태 관리 및 데이터 요청 처리
- MSW: API 모킹으로 백엔드 개발 전에도 테스트 가능한 환경
# OpenAPI Generator CLI 설치
pnpm add -D @openapitools/openapi-generator-cli
// package.json
{
"scripts": {
"generate-api": "openapi-generator-cli generate -i swagger.json -g typescript-axios -o src/api/generated --skip-validate-spec"
}
}
- Swagger 문서로부터 TypeScript 타입과 API 클라이언트를 자동 생성
- 생성된 코드는
src/api/generated
폴더에 저장되며, API 응답 타입과 호출 메서드를 포함
// shared/api/client.ts
import { Configuration, FacilityControllerApi } from '@/api/generated';
const config = new Configuration({
basePath: '' // Swagger 문서 경로와 일치
});
export const api = {
facility: new FacilityControllerApi(config)
};
-
shared/api/client.ts
에서 API 클라이언트를 중앙 관리 -
Configuration
객체를 통해baseURL
등 공통 설정을 관리 - 각 도메인별 API(예:
FacilityControllerApi
)를 구성하여 사용
프론트엔드의 API 연동은 다음 세 가지 레이어로 구성됩니다:
// entities/facility/api/facilityService.ts
import { api } from '@/shared/api/client';
import type { FacilityDetailsResponseDTO } from '@/api/generated';
export const facilityService = {
// 생성된 Response DTO 타입 활용
getFacilityDetail: async (id: string): Promise<FacilityDetailsResponseDTO> => {
// API 클라이언트를 통한 데이터 요청
const { data } = await api.facility.readFacilityDetails(id);
return data;
}
};
- API 통신 로직 담당
- API 클라이언트 사용
- 순수한 데이터 요청/응답 처리
A. 기본 구현 (React Query 없이)
// 직접 서비스 사용 시
const FacilityDetail = () => {
const [isLoading, setIsLoading] = useState(false);
const [error, setError] = useState<Error | null>(null);
const [data, setData] = useState<FacilityDetailsResponseDTO | null>(null);
const fetchData = async () => {
try {
setIsLoading(true);
const response = await facilityService.getFacilityDetail(id);
setData(response);
} catch (error) {
setError(error as Error);
toast.error('시설 정보를 불러오는데 실패했습니다.');
} finally {
setIsLoading(false);
}
};
useEffect(() => {
fetchData();
}, [id]);
// loading, error, data 상태에 따른 UI 렌더링
return (
<div>
{isLoading && <LoadingSpinner />}
{error && <ErrorMessage message={error.message} />}
{data && <FacilityInfo facility={data} />}
</div>
);
};
- UI 레이어에서 로딩, 에러 직접 상태 관리
-
useEffect
로 데이터 요청 - 사용자 피드백 처리
- UI 렌더링 로직
B. React Query 활용
const FacilityDetail = () => {
const { data, isLoading, error } = useFacilityDetail(id, {
enabled: !!id,
onError: (error) => {
toast.error('시설 정보를 불러오는데 실패했습니다.');
}
});
return (
<div>
{isLoading && <LoadingSpinner />}
{error && <ErrorMessage />}
{data && <FacilityInfo facility={data} />}
</div>
);
};
- Query Hook 사용
- React Query를 통한 상태 관리 자동화
- 선언적인 데이터 fetching
- 에러 및 로딩 상태 처리 간소화
// features/facility/model/constants.ts
export const QUERY_KEYS = {
facilityDetail: (id: string) => ['facility', 'detail', id] as const
};
// features/facility/model/queries.ts
import { useQuery } from '@tanstack/react-query';
import { facilityService } from '../api/facilityService';
export const useFacilityDetail = (id: string, options?: UseQueryOptions) => {
return useQuery({
queryKey: QUERY_KEYS.facilityDetail(id),
queryFn: () => facilityService.getFacilityDetail(id),
...options
});
};
- React Query를 활용한 서버 상태 관리
- 쿼리 키 관리
- 캐싱, 재시도 등 처리
MSW(Mock Service Worker)는 서비스 워커를 사용하여 네트워크 수준에서 API 요청을 가로채고 모의 응답을 제공합니다. 이를 통해 백엔드 API 완성 전에도 프론트엔드 개발을 진행할 수 있습니다.
// mocks/handlers/facility.ts
import { HttpResponse, http } from 'msw';
import type { FacilityDetailsResponseDTO } from '@/api/generated';
export const facilityHandlers = [
// Swagger 문서의 경로와 동일하게 설정
http.get<{ facilityId: string }>(
'/api/facility-detail/:facilityId',
({ params }) => {
// 생성된 DTO 타입과 동일한 형태로 응답
const mockData: FacilityDetailsResponseDTO = {
facilityId: params.facilityId,
// ... 나머지 필드
};
return HttpResponse.json(mockData);
}
)
];
- 실제 API가 완성되기 전에 모의 응답을 제공하는 핸들러를 설정
- Swagger 문서의 경로와 동일한 엔드포인트를 사용
- 생성된 DTO 타입과 동일한 구조로 응답을 작성하여 실제 API와 동일한 환경을 모사
- 새로운 Swagger 문서를 받기
-
pnpm generate-api
명령어 실행하여 타입과 API 클라이언트 재생성 - 생성된 코드에 맞춰 서비스 레이어 수정
- Query Hook 업데이트
- MSW 핸들러 수정
- 타입 단언(
as
) 사용 지양 - API 응답 구조를 반드시 확인
- 에러 처리 로직의 일관성 유지
- MSW 모의 데이터는 실제 API 응답과 동일하게 구성
-
타입 안정성:
- API 응답 타입 자동 생성
- 컴파일 타임에 타입 오류 감지
-
개발 효율성:
- API 스펙 변경 시 자동 동기화
- React Query를 통한 상태 관리 자동화
-
테스트 용이성:
- MSW를 통한 API 모킹
- 백엔드 의존성 없는 개발 가능