Swagger/OpenAPI 문서를 기반으로 axios/ky + TanStack Query (with Infinite Query) + FSD(Feature-Sliced Design) 패턴에 맞는 API 클라이언트를 자동으로 생성하는 도구입니다.
- 🔄 HTTP 클라이언트 선택 - axios 또는 ky 중 선택 가능
- 🚀 TanStack Query 완벽 지원
useQuery- 일반 조회useSuspenseQuery- Suspense 기반 조회useInfiniteQuery- 페이지네이션 자동 생성 ⭐ NEWuseMutation- 데이터 변경
- 📁 FSD(Feature-Sliced Design) 패턴 자동 적용
- ⚙️ Config 파일 지원 -
swagger-codegen.config.js로 설정 관리 - 👀 Watch 모드 - 파일 변경 감지 자동 재생성
- 🎯 Module Filtering - 특정 모듈만 선택적으로 생성
- 🔐 HTTP Basic Authentication 지원
- 📝 TypeScript 완전 지원 (타입 안전성)
- 🎨 프로젝트의 Prettier 설정 자동 적용
# npm
npm install -D swagger-fsd-gen
# yarn
yarn add -D swagger-fsd-gen
# pnpm
pnpm add -D swagger-fsd-gen프로젝트 루트에 swagger-codegen.config.js 파일을 생성합니다:
export default {
// Swagger 문서 URL
uri: process.env.SWAGGER_URL || 'http://localhost:8000/api-json',
// HTTP 클라이언트 선택 (axios 또는 ky)
httpClient: 'axios', // 기본값
// Basic Auth (선택사항)
username: process.env.SWAGGER_USERNAME,
password: process.env.SWAGGER_PASSWORD,
// 출력 경로 커스터마이징 (선택사항)
output: {
dto: 'src/shared/api/dto.ts',
api: 'src/entities/{moduleName}/api/index.ts',
instance: 'src/entities/{moduleName}/api/instance.ts',
queries: 'src/entities/{moduleName}/api/queries.ts',
mutations: 'src/entities/{moduleName}/api/mutations.ts',
},
// Module Filtering (선택사항)
// include: ['user', 'campaign'], // 특정 모듈만 생성
// exclude: ['admin', 'internal'], // 특정 모듈 제외
};# npm
npx generate-all
# yarn
yarn generate-all
# pnpm
pnpm generate-all# 기본 사용법
generate-all --uri https://api.example.com/swagger.json
# HTTP 클라이언트 지정
generate-all --uri https://api.example.com/swagger.json --http-client ky
# Watch 모드 (자동 재생성)
generate-all --uri https://api.example.com/swagger.json --watch
# Module Filtering
generate-all --uri https://api.example.com/swagger.json --include user,campaign
generate-all --uri https://api.example.com/swagger.json --exclude admin,internal
# Basic Auth
generate-all --uri https://api.example.com/swagger.json --username admin --password secret{
"scripts": {
"codegen": "generate-all",
"codegen:watch": "generate-all --watch"
}
}실행:
npm run codegen
npm run codegen:watchsrc/
├── shared/
│ └── api/
│ └── dto.ts # DTO 타입 정의
└── entities/
└── {moduleName}/ # Swagger 태그별 모듈
└── api/
├── index.ts # API 클래스
├── instance.ts # API 인스턴스
├── queries.ts # TanStack Query 훅
└── mutations.ts # TanStack Mutation 훅
export default {
httpClient: 'axios',
};장점:
- ✅ 가장 인기 있는 HTTP 클라이언트
- ✅ 훌륭한 TypeScript 지원
- ✅ Request/Response 인터셉터
- ✅ 더 나은 에러 핸들링
- ✅ 취소 토큰 지원
export default {
httpClient: 'ky',
};장점:
- ✅ 경량 (axios 대비 10배 작음)
- ✅ 모던한 fetch 기반
- ✅ 내장 재시도 기능
- ✅ 깔끔한 API
페이지네이션이 있는 엔드포인트는 useInfiniteQuery 훅이 자동으로 생성됩니다!
다음 쿼리 파라미터 중 하나라도 있으면 자동으로 Infinite Query가 생성됩니다:
page- 페이지 기반 (?page=1)cursor- 커서 기반 (?cursor=abc)offset- 오프셋 기반 (?offset=0&limit=20)pageToken- 토큰 기반 (?pageToken=xyz)
Swagger 정의:
/api/campaigns:
get:
parameters:
- name: page
in: query
schema:
type: integer
- name: category
in: query
schema:
type: string생성된 코드 (queries.ts):
// 일반 Query
export const useGetCampaignsQuery = (params?: { page?: number; category?: string }) => {
return useQuery({
queryKey: ['campaigns', params],
queryFn: () => campaignApi.getCampaigns(params),
});
};
// ⭐ Infinite Query (자동 생성!)
export const useGetCampaignsInfiniteQuery = (
params?: { category?: string }, // page는 제외됨
options?: UseInfiniteQueryOptions
) => {
return useInfiniteQuery({
queryKey: ['campaigns', params],
queryFn: ({ pageParam }) => campaignApi.getCampaigns({ ...params, page: pageParam }),
initialPageParam: 1,
getNextPageParam: (lastPage) => {
if (!lastPage?.hasNext) return undefined;
return (lastPage?.page ?? 0) + 1;
},
getPreviousPageParam: (firstPage) => {
if ((firstPage?.page ?? 1) <= 1) return undefined;
return (firstPage?.page ?? 1) - 1;
},
...options,
});
};컴포넌트에서 사용:
function CampaignList() {
const { data, fetchNextPage, hasNextPage, isFetching } = useGetCampaignsInfiniteQuery({
category: 'food',
});
return (
<div>
{data?.pages.map(page =>
page.items.map(campaign => (
<CampaignCard key={campaign.id} {...campaign} />
))
)}
{hasNextPage && (
<button onClick={() => fetchNextPage()} disabled={isFetching}>
더 보기
</button>
)}
</div>
);
}개발 중 Swagger 문서가 변경될 때 자동으로 코드를 재생성합니다.
# CLI
generate-all --watch
# Config
{
"scripts": {
"codegen:watch": "generate-all --watch"
}
}특징:
- 로컬 파일:
chokidar로 변경 감지 - 원격 URL: 10초마다 ETag/Last-Modified 체크
필요한 모듈만 선택적으로 생성할 수 있습니다.
export default {
include: ['user', 'campaign', 'schedule'],
};또는
generate-all --include user,campaign,scheduleexport default {
exclude: ['admin', 'internal'],
};또는
generate-all --exclude admin,internal주의: include와 exclude는 동시에 사용할 수 없습니다.
| 옵션 | 단축키 | 설명 | 기본값 |
|---|---|---|---|
--uri |
-u |
Swagger 문서 URL/경로 | 필수 |
--http-client |
-hc |
HTTP 클라이언트 (axios/ky) | axios |
--username |
-un |
Basic Auth 사용자명 | - |
--password |
-pw |
Basic Auth 비밀번호 | - |
--dto-output-path |
-dp |
DTO 파일 경로 | src/shared/api/dto.ts |
--api-output-path |
-ap |
API 클래스 경로 | src/entities/{moduleName}/api/index.ts |
--api-instance-output-path |
-aip |
API 인스턴스 경로 | src/entities/{moduleName}/api/instance.ts |
--query-output-path |
-qp |
Query 훅 경로 | src/entities/{moduleName}/api/queries.ts |
--mutation-output-path |
-mp |
Mutation 훅 경로 | src/entities/{moduleName}/api/mutations.ts |
--project-template |
-pt |
커스텀 템플릿 경로 | - |
--watch |
-w |
Watch 모드 활성화 | false |
--include |
- | 포함할 모듈 (쉼표로 구분) | - |
--exclude |
- | 제외할 모듈 (쉼표로 구분) | - |
export default {
// 필수
uri: string,
// HTTP 클라이언트
httpClient: 'axios' | 'ky', // 기본값: 'axios'
// 인증
username?: string,
password?: string,
// 출력 경로
output?: {
dto?: string,
api?: string,
instance?: string,
queries?: string,
mutations?: string,
},
// 템플릿
templates?: string,
// Module Filtering
include?: string[],
exclude?: string[],
};자체 EJS 템플릿을 사용하려면:
export default {
templates: './custom-templates',
};템플릿 구조:
custom-templates/
├── modular/
│ ├── axios/
│ │ └── procedure-call.ejs
│ ├── ky/
│ │ └── procedure-call.ejs
│ ├── api.ejs
│ ├── data-contracts.ejs
│ └── route-docs.ejs
└── tanstack-query/
├── axios/
│ └── route-types.ejs
├── ky/
│ └── route-types.ejs
└── api.ejs
.env 파일:
SWAGGER_URL=http://localhost:8000/api-json
SWAGGER_USERNAME=admin
SWAGGER_PASSWORD=secretswagger-codegen.config.js:
import 'dotenv/config';
export default {
uri: process.env.SWAGGER_URL,
username: process.env.SWAGGER_USERNAME,
password: process.env.SWAGGER_PASSWORD,
};HTTP Client 기본값 변경
- v1.x:
ky만 지원 - v2.0:
axios기본값,ky선택 가능
기존 ky 사용자:
// swagger-codegen.config.js
export default {
httpClient: 'ky',
};- ✅ HTTP 클라이언트 선택 (axios/ky)
- ✅ 자동 Infinite Query 생성
- ✅ Config 파일 지원
- ✅ Watch 모드
- ✅ Module Filtering
기여는 언제나 환영입니다! 이슈와 PR을 자유롭게 제출해주세요.
MIT © sen2y