# API 사용 가이드 이 문서는 데이터베이스에 데이터를 생성하는 API의 사용 방법을 설명합니다. ## 📋 목차 1. [기본 설정](#기본-설정) 2. [사용자 API](#1-사용자-api) 3. [교육과정 API](#2-교육과정-api) 4. [강좌 API](#3-강좌-api) 5. [공지사항 API](#4-공지사항-api) 6. [에러 처리](#에러-처리) 7. [실전 예제](#실전-예제) --- ## 기본 설정 ### 환경 변수 `.env` 파일에 데이터베이스 연결 정보가 설정되어 있어야 합니다: ```env DATABASE_URL="postgresql://user:password@localhost:5432/dbname" ``` ### API 기본 URL - 개발 환경: `http://localhost:3000/api` - 프로덕션: `https://your-domain.com/api` --- ## 1. 사용자 API ### POST /api/users - 사용자 생성 새로운 사용자를 생성합니다. #### 요청 ```typescript const response = await fetch('/api/users', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ email: 'user@example.com', password: 'hashed_password_here', // 실제로는 해시화된 비밀번호 name: '홍길동', phone: '010-1234-5678', // 선택사항 gender: 'M', // 선택사항: 'M' 또는 'F' birthdate: '1990-01-01', // 선택사항: YYYY-MM-DD 형식 role: 'LEARNER', // 선택사항: 'LEARNER' 또는 'ADMIN' (기본값: 'LEARNER') status: 'ACTIVE', // 선택사항: 'ACTIVE' 또는 'INACTIVE' (기본값: 'ACTIVE') }), }); const data = await response.json(); ``` #### 성공 응답 (201) ```json { "message": "사용자가 성공적으로 생성되었습니다.", "user": { "id": "550e8400-e29b-41d4-a716-446655440000", "email": "user@example.com", "name": "홍길동", "phone": "010-1234-5678", "gender": "M", "birthdate": "1990-01-01T00:00:00.000Z", "role": "LEARNER", "status": "ACTIVE", "joinDate": "2024-11-21T00:00:00.000Z", "createdAt": "2024-11-21T00:00:00.000Z", "updatedAt": "2024-11-21T00:00:00.000Z" } } ``` #### 에러 응답 **400 Bad Request** - 필수 필드 누락 ```json { "error": "이메일, 비밀번호, 이름은 필수입니다." } ``` **409 Conflict** - 이메일 중복 ```json { "error": "이미 존재하는 이메일입니다." } ``` ### GET /api/users - 사용자 목록 조회 사용자 목록을 조회합니다. 필터링 및 페이지네이션을 지원합니다. #### 요청 ```typescript // 전체 사용자 조회 const response = await fetch('/api/users'); // 필터링 및 페이지네이션 const response = await fetch('/api/users?role=LEARNER&status=ACTIVE&page=1&limit=10'); const data = await response.json(); ``` #### 쿼리 파라미터 - `role` (선택): `LEARNER` 또는 `ADMIN` - `status` (선택): `ACTIVE` 또는 `INACTIVE` - `page` (선택): 페이지 번호 (기본값: 1) - `limit` (선택): 페이지당 항목 수 (기본값: 10) #### 성공 응답 (200) ```json { "users": [ { "id": "550e8400-e29b-41d4-a716-446655440000", "email": "user@example.com", "name": "홍길동", "role": "LEARNER", "status": "ACTIVE", ... } ], "pagination": { "page": 1, "limit": 10, "total": 30, "totalPages": 3 } } ``` --- ## 2. 교육과정 API ### POST /api/courses - 교육과정 생성 새로운 교육과정을 생성합니다. #### 요청 ```typescript const response = await fetch('/api/courses', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ courseName: '웹 개발 기초', instructorId: 'instructor-uuid-here', // 필수: 강사(ADMIN 역할)의 ID createdById: 'admin-uuid-here', // 선택사항: 등록자 ID (기본값: instructorId) }), }); const data = await response.json(); ``` #### 성공 응답 (201) ```json { "message": "교육과정이 성공적으로 생성되었습니다.", "course": { "id": "550e8400-e29b-41d4-a716-446655440000", "courseName": "웹 개발 기초", "instructorId": "instructor-uuid", "createdById": "admin-uuid", "createdAt": "2024-11-21T00:00:00.000Z", "instructor": { "id": "instructor-uuid", "name": "최예준", "email": "instructor@example.com" }, "createdBy": { "id": "admin-uuid", "name": "관리자" } } } ``` #### 에러 응답 **400 Bad Request** - 필수 필드 누락 ```json { "error": "교육과정명과 강사 ID는 필수입니다." } ``` **404 Not Found** - 강사를 찾을 수 없음 ```json { "error": "강사를 찾을 수 없습니다." } ``` ### GET /api/courses - 교육과정 목록 조회 교육과정 목록을 조회합니다. #### 요청 ```typescript // 전체 교육과정 조회 const response = await fetch('/api/courses'); // 특정 강사의 교육과정 조회 const response = await fetch('/api/courses?instructorId=instructor-uuid&page=1&limit=10'); const data = await response.json(); ``` #### 쿼리 파라미터 - `instructorId` (선택): 강사 ID로 필터링 - `page` (선택): 페이지 번호 (기본값: 1) - `limit` (선택): 페이지당 항목 수 (기본값: 10) --- ## 3. 강좌 API ### POST /api/lessons - 강좌 생성 새로운 강좌를 생성합니다. #### 요청 ```typescript const response = await fetch('/api/lessons', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ courseId: 'course-uuid-here', // 필수: 교육과정 ID lessonName: 'HTML 기초', // 필수: 강좌명 learningGoal: 'HTML의 기본 문법을 이해하고 활용할 수 있다.', // 선택사항: 학습 목표 createdById: 'admin-uuid-here', // 선택사항: 등록자 ID }), }); const data = await response.json(); ``` #### 성공 응답 (201) ```json { "message": "강좌가 성공적으로 생성되었습니다.", "lesson": { "id": "550e8400-e29b-41d4-a716-446655440000", "courseId": "course-uuid", "lessonName": "HTML 기초", "learningGoal": "HTML의 기본 문법을 이해하고 활용할 수 있다.", "createdAt": "2024-11-21T00:00:00.000Z", "course": { "id": "course-uuid", "courseName": "웹 개발 기초" }, "createdBy": { "id": "admin-uuid", "name": "관리자" }, "_count": { "videos": 0, "vrContents": 0, "questions": 0 } } } ``` ### GET /api/lessons - 강좌 목록 조회 강좌 목록을 조회합니다. #### 요청 ```typescript // 전체 강좌 조회 const response = await fetch('/api/lessons'); // 특정 교육과정의 강좌 조회 const response = await fetch('/api/lessons?courseId=course-uuid&page=1&limit=10'); const data = await response.json(); ``` --- ## 4. 공지사항 API ### POST /api/notices - 공지사항 생성 새로운 공지사항을 생성합니다. #### 요청 ```typescript const response = await fetch('/api/notices', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ title: '공지사항 제목', content: '공지사항 내용입니다.\n여러 줄로 작성할 수 있습니다.', writerId: 'admin-uuid-here', // 필수: 작성자 ID hasAttachment: false, // 선택사항: 첨부파일 여부 (기본값: false) }), }); const data = await response.json(); ``` #### 성공 응답 (201) ```json { "message": "공지사항이 성공적으로 생성되었습니다.", "notice": { "id": "550e8400-e29b-41d4-a716-446655440000", "title": "공지사항 제목", "content": "공지사항 내용입니다.\n여러 줄로 작성할 수 있습니다.", "writerId": "admin-uuid", "views": 0, "hasAttachment": false, "date": "2024-11-21T00:00:00.000Z", "writer": { "id": "admin-uuid", "name": "관리자", "email": "admin@example.com" } } } ``` ### GET /api/notices - 공지사항 목록 조회 공지사항 목록을 조회합니다. #### 요청 ```typescript // 전체 공지사항 조회 const response = await fetch('/api/notices'); // 특정 작성자의 공지사항 조회 const response = await fetch('/api/notices?writerId=admin-uuid&page=1&limit=10'); const data = await response.json(); ``` --- ## 에러 처리 모든 API는 일관된 에러 응답 형식을 사용합니다: ```typescript try { const response = await fetch('/api/users', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(userData), }); if (!response.ok) { const error = await response.json(); console.error('에러:', error.error); // 에러 처리 로직 return; } const data = await response.json(); console.log('성공:', data); } catch (error) { console.error('네트워크 오류:', error); } ``` ### HTTP 상태 코드 - `200` - 성공 (GET 요청) - `201` - 생성 성공 (POST 요청) - `400` - 잘못된 요청 (필수 필드 누락 등) - `404` - 리소스를 찾을 수 없음 - `409` - 충돌 (중복 데이터 등) - `500` - 서버 오류 --- ## 실전 예제 ### React 컴포넌트에서 사용하기 ```typescript 'use client'; import { useState } from 'react'; export default function CreateUserForm() { const [formData, setFormData] = useState({ email: '', password: '', name: '', role: 'LEARNER', }); const [loading, setLoading] = useState(false); const [message, setMessage] = useState(''); const handleSubmit = async (e: React.FormEvent) => { e.preventDefault(); setLoading(true); setMessage(''); try { const response = await fetch('/api/users', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify(formData), }); const data = await response.json(); if (!response.ok) { setMessage(`오류: ${data.error}`); return; } setMessage('사용자가 성공적으로 생성되었습니다!'); // 폼 초기화 setFormData({ email: '', password: '', name: '', role: 'LEARNER' }); } catch (error) { setMessage('네트워크 오류가 발생했습니다.'); } finally { setLoading(false); } }; return (
setFormData({ ...formData, email: e.target.value })} required /> setFormData({ ...formData, password: e.target.value })} required /> setFormData({ ...formData, name: e.target.value })} required /> {message &&

{message}

}
); } ``` ### Server Component에서 사용하기 ```typescript // app/admin/users/page.tsx import { prisma } from '@/lib/prisma'; export default async function UsersPage() { const users = await prisma.user.findMany({ take: 10, orderBy: { createdAt: 'desc' }, }); return (

사용자 목록

); } ``` ### cURL로 테스트하기 ```bash # 사용자 생성 curl -X POST http://localhost:3000/api/users \ -H "Content-Type: application/json" \ -d '{ "email": "test@example.com", "password": "test123", "name": "테스트 사용자", "role": "LEARNER" }' # 사용자 목록 조회 curl http://localhost:3000/api/users?role=LEARNER&page=1&limit=10 # 교육과정 생성 curl -X POST http://localhost:3000/api/courses \ -H "Content-Type: application/json" \ -d '{ "courseName": "웹 개발 기초", "instructorId": "instructor-uuid-here" }' ``` --- ## 🔒 보안 고려사항 1. **비밀번호 해시화**: 실제 프로덕션에서는 bcrypt 등을 사용하여 비밀번호를 해시화해야 합니다. 2. **인증/인가**: 현재 API는 인증이 없습니다. 프로덕션에서는 JWT 또는 세션 기반 인증을 추가해야 합니다. 3. **입력 검증**: 클라이언트 측 검증 외에도 서버 측 검증이 필요합니다. 4. **CORS 설정**: 필요시 CORS 설정을 추가해야 합니다. --- ## 📚 추가 리소스 - [Next.js API Routes 문서](https://nextjs.org/docs/app/building-your-application/routing/route-handlers) - [Prisma Client 문서](https://www.prisma.io/docs/concepts/components/prisma-client)