무료 챕터
5. REST API 자동 생성: 코드 한 줄 없이
by leancle•2025. 8. 9.
🚀 Claude가 만드는 완벽한 API
데이터베이스 스키마만 있다면, Claude가 자동으로 완전한 REST API를 생성해줍니다. Next.js, Express, FastAPI 등 원하는 프레임워크로!
🎨 API 설계 자동화
스키마 분석 및 API 설계
You: "현재 데이터베이스 구조를 분석해서 REST API를 설계해줘"
Claude: 데이터베이스 스키마를 분석하겠습니다.
[MCP로 스키마 분석 중...]
📊 발견된 테이블: 3개
- users (사용자)
- products (제품)
- orders (주문)
🔗 관계 분석:
- orders.user_id → users.id (N:1)
- orders.product_id → products.id (N:1)
📝 추천 API 엔드포인트:
## Users API
GET /api/users # 사용자 목록
GET /api/users/:id # 사용자 상세
POST /api/users # 사용자 생성
PUT /api/users/:id # 사용자 수정
DELETE /api/users/:id # 사용자 삭제
GET /api/users/:id/orders # 사용자 주문 목록
## Products API
GET /api/products # 제품 목록
GET /api/products/:id # 제품 상세
POST /api/products # 제품 생성
PUT /api/products/:id # 제품 수정
DELETE /api/products/:id # 제품 삭제
## Orders API
GET /api/orders # 주문 목록
GET /api/orders/:id # 주문 상세
POST /api/orders # 주문 생성
PUT /api/orders/:id # 주문 상태 변경
DELETE /api/orders/:id # 주문 취소
🔨 Next.js API Routes 생성
자동 코드 생성
You: "Next.js App Router로 users API를 만들어줘"
Claude: Next.js 13+ App Router용 API를 생성하겠습니다.
[MCP로 테이블 구조 분석 중...]
📁 생성할 파일 구조:
app/
└── api/
└── users/
├── route.ts # GET(목록), POST(생성)
└── [id]/
└── route.ts # GET(상세), PUT(수정), DELETE(삭제)
app/api/users/route.ts:
import { NextRequest, NextResponse } from 'next/server';
import { createClient } from '@supabase/supabase-js';
const supabase = createClient(
process.env.NEXT_PUBLIC_SUPABASE_URL!,
process.env.SUPABASE_SERVICE_KEY!
);
// GET: 사용자 목록 조회
export async function GET(request: NextRequest) {
try {
const { searchParams } = new URL(request.url);
const page = parseInt(searchParams.get('page') || '1');
const limit = parseInt(searchParams.get('limit') || '10');
const search = searchParams.get('search') || '';
let query = supabase
.from('users')
.select('*', { count: 'exact' });
// 검색 필터
if (search) {
query = query.or(`name.ilike.%${search}%,email.ilike.%${search}%`);
}
// 페이지네이션
const from = (page - 1) * limit;
const to = from + limit - 1;
query = query.range(from, to);
const { data, error, count } = await query;
if (error) throw error;
return NextResponse.json({
data,
pagination: {
page,
limit,
total: count,
totalPages: Math.ceil((count || 0) / limit)
}
});
} catch (error) {
return NextResponse.json(
{ error: 'Failed to fetch users' },
{ status: 500 }
);
}
}
// POST: 새 사용자 생성
export async function POST(request: NextRequest) {
try {
const body = await request.json();
// 유효성 검사
if (!body.email || !body.name) {
return NextResponse.json(
{ error: 'Email and name are required' },
{ status: 400 }
);
}
const { data, error } = await supabase
.from('users')
.insert([body])
.select()
.single();
if (error) throw error;
return NextResponse.json(data, { status: 201 });
} catch (error) {
return NextResponse.json(
{ error: 'Failed to create user' },
{ status: 500 }
);
}
}
🛡️ 인증 및 권한 관리
JWT 인증 추가
You: "API에 JWT 인증을 추가해줘"
Claude: JWT 인증 미들웨어를 추가하겠습니다.
**middleware.ts:**
```typescript
import { NextRequest, NextResponse } from 'next/server';
import { jwtVerify } from 'jose';
export async function middleware(request: NextRequest) {
// 공개 경로는 인증 스킵
const publicPaths = ['/api/auth/login', '/api/auth/register'];
if (publicPaths.includes(request.nextUrl.pathname)) {
return NextResponse.next();
}
// Bearer 토큰 확인
const token = request.headers.get('authorization')?.replace('Bearer ', '');
if (!token) {
return NextResponse.json(
{ error: 'Authentication required' },
{ status: 401 }
);
}
try {
const secret = new TextEncoder().encode(process.env.JWT_SECRET!);
const { payload } = await jwtVerify(token, secret);
// 요청에 사용자 정보 추가
const requestHeaders = new Headers(request.headers);
requestHeaders.set('x-user-id', payload.sub as string);
requestHeaders.set('x-user-role', payload.role as string);
return NextResponse.next({
request: {
headers: requestHeaders,
},
});
} catch (error) {
return NextResponse.json(
{ error: 'Invalid token' },
{ status: 401 }
);
}
}
export const config = {
matcher: '/api/:path*',
};
📊 API 문서 자동 생성
OpenAPI/Swagger 문서
You: "API 문서를 자동으로 생성해줘"
Claude: OpenAPI 3.0 명세서를 생성하겠습니다.
**api-docs.yaml:**
```yaml
openapi: 3.0.0
info:
title: MCP Demo API
version: 1.0.0
description: Supabase MCP로 자동 생성된 API
servers:
- url: http://localhost:3000/api
description: 개발 서버
components:
securitySchemes:
bearerAuth:
type: http
scheme: bearer
bearerFormat: JWT
schemas:
User:
type: object
required:
- email
- name
properties:
id:
type: string
format: uuid
email:
type: string
format: email
name:
type: string
created_at:
type: string
format: date-time
paths:
/users:
get:
summary: 사용자 목록 조회
security:
- bearerAuth: []
parameters:
- name: page
in: query
schema:
type: integer
default: 1
- name: limit
in: query
schema:
type: integer
default: 10
- name: search
in: query
schema:
type: string
responses:
200:
description: 성공
content:
application/json:
schema:
type: object
properties:
data:
type: array
items:
$ref: '#/components/schemas/User'
🧪 API 테스트 자동화
테스트 코드 생성
You: "users API에 대한 테스트 코드를 작성해줘"
Claude: Jest와 Supertest를 사용한 테스트 코드를 생성하겠습니다.
**__tests__/api/users.test.ts:**
```typescript
import { createMocks } from 'node-mocks-http';
import { GET, POST } from '@/app/api/users/route';
describe('/api/users', () => {
describe('GET', () => {
it('should return users list', async () => {
const { req, res } = createMocks({
method: 'GET',
query: { page: '1', limit: '10' },
});
const response = await GET(req);
const json = await response.json();
expect(response.status).toBe(200);
expect(json).toHaveProperty('data');
expect(json).toHaveProperty('pagination');
expect(Array.isArray(json.data)).toBe(true);
});
it('should filter users by search term', async () => {
const { req, res } = createMocks({
method: 'GET',
query: { search: 'john' },
});
const response = await GET(req);
const json = await response.json();
expect(response.status).toBe(200);
json.data.forEach(user => {
expect(
user.name.toLowerCase().includes('john') ||
user.email.toLowerCase().includes('john')
).toBe(true);
});
});
});
describe('POST', () => {
it('should create a new user', async () => {
const { req, res } = createMocks({
method: 'POST',
body: {
email: 'test@example.com',
name: 'Test User'
},
});
const response = await POST(req);
const json = await response.json();
expect(response.status).toBe(201);
expect(json).toHaveProperty('id');
expect(json.email).toBe('test@example.com');
});
it('should validate required fields', async () => {
const { req, res } = createMocks({
method: 'POST',
body: { email: 'test@example.com' }, // name 누락
});
const response = await POST(req);
expect(response.status).toBe(400);
});
});
});
🎬 다음 챕터 예고
"실시간 데이터 동기화" - Supabase Realtime과 MCP를 활용한 실시간 협업 앱 만들기!