
Next.js App Router를 사용하면서 서버 로직을 처리하는 방법은 크게 두 가지가 있다.
두 방식 모두 서버에서 실행되지만,
👉 사용 목적과 구조가 다르기 때문에 구분해서 이해하는 것이 중요하다.
이 글에서는 Route Handlers를 중심으로
👉 언제 사용하고, 어떻게 구성하는지에 초점을 맞춰 정리하려고 한다.
Route Handlers는 App Router에서 사용하는 API 서버 기능이다.
기존 pages/api 방식 대신
👉 app/api/*/route.ts 구조를 사용한다.
// app/api/posts/route.ts
export async function GET() {
return Response.json({ message: 'Hello World' });
}
Route Handlers는 HTTP 메서드별로 함수를 정의한다.
export async function POST(request: Request) {
const body = await request.json();
return Response.json({
message: 'Post created',
data: body,
});
}
Route Handler는 요청이 들어올 때마다 실행되는
👉 서버 함수이다.
Client → API Route → DB → Response
export async function POST(request: Request) {
const data = await request.json();
await db.post.create({
data,
});
return Response.json({ success: true });
}
두 기능은 역할이 겹쳐 보이지만, 실제로는 용도가 다르다.
| 구분 | Route Handlers | Server Actions |
|---|---|---|
| 호출 방식 | HTTP 요청 | 함수 호출 |
| 사용 위치 | API 서버 | 컴포넌트 |
| 용도 | 외부 API / 백엔드 로직 | UI 기반 Mutation |
| 구조 | RESTful | 함수 기반 |
<form action={createPost}>
👉 Route Handler → API 중심
👉 Server Action → UI 중심
Route Handlers에서도 캐싱 전략을 적용할 수 있다.
export async function GET() {
const data = await fetch('https://api.example.com', {
next: { revalidate: 60 },
});
return Response.json(data);
}
revalidate 사용 가능Route Handler 자체는 요청마다 실행되지만,
내부 fetch는 Next.js 캐싱 전략을 따른다.
필요한 경우 라우트 단위로 동적 처리도 가능하다.
export const dynamic = 'force-dynamic';
👉 항상 최신 데이터를 기준으로 동작
Route Handler에서는 기본 Request, Response 대신
Next.js에서 제공하는 확장 객체를 사용할 수 있다.
import { NextRequest } from 'next/server';
export async function GET(request: NextRequest) {
const searchParams = request.nextUrl.searchParams;
const id = searchParams.get('id');
return Response.json({ id });
}
import { NextResponse } from 'next/server';
export async function GET() {
return NextResponse.json({ message: 'Hello' });
}
app/api/*/route.ts 구조 사용Route Handlers는 API 중심의 서버 로직을 구성하는 방식이며,
외부 요청 처리나 REST 구조가 필요한 경우에 적합하다.
Next.js App Router에서는 서버 로직을 처리하는 방식이 하나로 고정되어 있지 않다.
Route Handlers와 Server Actions는 모두 서버에서 실행되지만,
👉 어떤 방식으로 연결되는지에 따라 역할이 달라진다.
이 기준으로 구분하면
상황에 맞는 구조를 더 명확하게 선택할 수 있다.