무료 챕터

5. REST API 자동 생성: 코드 한 줄 없이

by leancle2025. 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를 활용한 실시간 협업 앱 만들기!