라우트 핸들러 (Route Handlers)
서버 액션(Server Actions)이 폼 전송에 특화되어 있다면, 모바일 앱이나 외부 서비스에 순수한 JSON 데이터(REST API)를 제공해야 할 때는 어떻게 할까요? 이때 사용하는 것이 바로 라우트 핸들러(Route Handlers)입니다.
라우트 핸들러의 사용 원칙
- 파일명은 무조건
route.ts: 폴더 구조 기반 라우팅에서,page.tsx가 UI를 담당한다면route.ts는 백엔드 API를 담당합니다. (같은 폴더에 두 개를 같이 둘 수 없습니다.) - HTTP 메서드 명명:
GET,POST,PUT,DELETE등의 이름으로 함수를 export 하면 Next.js가 해당 메서드의 요청을 자동으로 매칭해 줍니다. - 웹 표준 API 사용: Node.js 전용 객체가 아닌, 현대 브라우저 표준인
Request와Response객체(Next.js 확장은 NextRequest, NextResponse)를 사용하여 매우 직관적입니다.
// ==========================================
// 📂 app/api/users/route.ts
// 완벽한 REST API 서버 구축 예제
// ==========================================
import { NextRequest, NextResponse } from 'next/server';
// 1️⃣ HTTP GET 요청 처리: URL /api/users 로 GET 요청이 올 때 실행됨
export async function GET(request: NextRequest) {
// 쿼리스트링(Query Parameter) 읽기 예: /api/users?id=123
const searchParams = request.nextUrl.searchParams;
const id = searchParams.get('id');
// DB에서 유저 목록 조회 로직 (가상)
const users = [
{ id: 1, name: '김민수', role: 'admin' },
{ id: 2, name: '이영희', role: 'user' },
];
// NextResponse.json()을 사용하면 완벽한 JSON 응답을 전송합니다.
return NextResponse.json(users, { status: 200 });
}
// 2️⃣ HTTP POST 요청 처리: URL /api/users 로 데이터 등록 요청이 올 때 실행됨
export async function POST(request: NextRequest) {
try {
// 클라이언트가 보낸 JSON Body 읽어오기
const body = await request.json();
// DB 저장 로직 (가상)
const newUser = { id: 3, ...body };
console.log("새 회원가입 완료:", newUser);
return NextResponse.json(
{ message: '유저가 성공적으로 생성되었습니다.', user: newUser },
{ status: 201 } // 201 Created 응답 코드
);
} catch (error) {
return NextResponse.json(
{ error: '잘못된 요청 양식입니다.' },
{ status: 400 } // 에러 처리도 매우 깔끔하게 가능!
);
}
}