stack-analysis
CHAPTER 51 / 90
읽기 약 2분
FUNCTION
OpenAPI/Swagger 자동 문서화
핵심 개념
OpenAPI 3.1·zod-openapi·Swagger UI·CI 검증 — 문서 = 코드.
본문
OpenAPI 3.1 — zod-openapi
pnpm add zod-openapi @asteasolutions/zod-to-openapi// schemas/post.ts
import { z } from 'zod';
import { extendZodWithOpenApi } from '@asteasolutions/zod-to-openapi';
extendZodWithOpenApi(z);
export const PostSchema = z.object({
id: z.string().openapi({ example: 'p_abc123' }),
title: z.string().min(1).max(200).openapi({ example: '오늘의 글' }),
content: z.string().openapi({ example: '본문...' }),
authorId: z.string(),
published: z.boolean(),
createdAt: z.string().datetime(),
}).openapi('Post');
export const CreatePostSchema = PostSchema.pick({
title: true, content: true,
}).openapi('CreatePost');
export const PostListSchema = z.object({
items: z.array(PostSchema),
nextCursor: z.string().nullable(),
}).openapi('PostList');라우트 등록
import { OpenAPIRegistry, OpenApiGeneratorV31 } from '@asteasolutions/zod-to-openapi';
const registry = new OpenAPIRegistry();
registry.registerPath({
method: 'get',
path: '/posts',
description: '게시물 목록 조회 (cursor 페이지네이션)',
summary: '게시물 목록',
tags: ['Posts'],
request: {
query: z.object({
limit: z.coerce.number().int().min(1).max(100).default(20),
cursor: z.string().optional(),
}),
},
responses: {
200: {
description: '게시물 목록',
content: { 'application/json': { schema: PostListSchema } },
},
401: {
description: '인증 실패',
content: { 'application/problem+json': { schema: ProblemSchema } },
},
},
});
registry.registerPath({
method: 'post',
path: '/posts',
description: '새 게시물 생성',
tags: ['Posts'],
security: [{ bearerAuth: [] }],
request: {
body: { content: { 'application/json': { schema: CreatePostSchema } } },
},
responses: {
201: { description: '생성됨', content: { 'application/json': { schema: PostSchema } } },
400: { description: '검증 실패', content: { 'application/problem+json': { schema: ProblemSchema } } },
},
});
registry.registerComponent('securitySchemes', 'bearerAuth', {
type: 'http',
scheme: 'bearer',
bearerFormat: 'JWT',
});
// 문서 생성
const generator = new OpenApiGeneratorV31(registry.definitions);
const document = generator.generateDocument({
openapi: '3.1.0',
info: {
title: 'My API',
version: '1.0.0',
description: '...',
},
servers: [{ url: 'https://api.example.com' }],
});
// 정적 파일 또는 동적 엔드포인트
fs.writeFileSync('openapi.json', JSON.stringify(document, null, 2));Swagger UI 호스팅
import swaggerUi from 'swagger-ui-express';
app.get('/openapi.json', (req, res) => res.json(document));
app.use('/docs', swaggerUi.serve, swaggerUi.setup(document, {
customCss: '.swagger-ui .topbar { display: none }',
customSiteTitle: 'My API Docs',
}));
// 또는 Scalar (모던 UI)
import { apiReference } from '@scalar/express-api-reference';
app.use('/docs', apiReference({
spec: { url: '/openapi.json' },
theme: 'purple',
}));검증 + 문서 = 같은 스키마
// 라우트 핸들러 — Zod로 검증 + OpenAPI 자동 생성
router.post('/posts', asyncHandler(async (req, res) => {
const data = CreatePostSchema.parse(req.body); // 동일 스키마
const post = await postService.create(req.user!.id, data);
res.status(201).json(post);
}));
// → 검증 실패 = 400 RFC 7807
// → 성공 = 201 + PostSchema
// → 문서와 실제 동작 100% 일치CI 검증
# .github/workflows/api-docs.yml
- name: Generate OpenAPI
run: pnpm generate:openapi
- name: Validate OpenAPI
run: pnpm dlx @redocly/cli lint openapi.json
- name: Diff against main
run: |
git diff main openapi.json
if [ $? -ne 0 ]; then
echo "API spec changed - reviewer check required"
fi
- name: Breaking change detection
run: |
pnpm dlx oasdiff breaking main:openapi.json HEAD:openapi.json클라이언트 SDK 자동 생성
# TypeScript
pnpm dlx openapi-typescript openapi.json -o ./generated/api.ts
# 또는 풀 SDK
pnpm dlx @hey-api/openapi-ts -i openapi.json -o ./generated -c @hey-api/client-fetch
# Python
pnpm dlx openapi-python-client generate --url openapi.json다음 챕터
CH.52 "tRPC: 타입 안전 API의 미래".
AI 프롬프트
🤖 AI에게 잘 물어보는 법 — 모델·전략별 프롬프트
Claude
무료: Sonnet 4.6 / Pro $20/mo: Opus 4.6
내 코드의 API 문서화 부분을 분석해서 실전 분석 + 개선 우선순위를 알려줘.
ChatGPT
무료: GPT-5.5 / Plus $20/mo: GPT-5.5 Pro
API 문서화 관련 인기 라이브러리/패턴 5개를 비교 분석해서 패턴 추출를 알려줘.
Gemini
무료: 2.5 Flash / Pro $19.99/mo: 3.1 Pro
내 프로젝트 전체에서 API 문서화 최적화 가능 위치를 보고해줘.
Grok
무료: Grok 4.1 / SuperGrok $30/mo
2026년 한국 백엔드 시장의 API 문서화 트렌드를 솔직히 알려줘.
⭐ 이것만 기억하세요
OpenAPI/Swagger 자동 문서화는 이 3가지만 확실히 잡으세요
1.Zod 스키마 = 검증 + OpenAPI 문서 — 단일 진실 공급원
2.Swagger UI/Scalar로 인터랙티브 문서 — 팀·외부 개발자 친화
3.CI에서 spec lint + breaking change 검출 — 자동 안전망
공유하기
진행도 51 / 90