5.2
App Router의 Route Handlers
Route Handlers는 웹의 Request와 Response API를 활용하여 백엔드 API를 만들 수 있게 해주는 App Router의 기능입니다. Pages Router에 API Routes가 있었다면, App Router에는 Route Handlers가 있는 것이죠. Route Handlers를 사용하기 위해서는 app 폴더 내에 만들고자 하는 API 경로대로 폴더를 만들고, 그 안에 route.js 또는 route.ts 라는 이름의 파일을 만들어서 API와 관련된 코드를 작성하면 됩니다.
Route Handlers를 사용할 때 유의할 점은 Route Handlers는 app 폴더 내부 어디에나 위치할 수 있지만, 아래 표에 나타난 것처럼 page.js와 동일한 route segment level에 route.js 파일이 존재해서는 안 됩니다. 만약 그렇게 할 경우 충돌이 발생하게 되어 제대로 작동하지 않게 됩니다. 그래서 보통은 충돌을 막기 위해서 app 폴더 내에 api라는 폴더를 만들고 그 안에 Route Handlers들을 배치합니다.
| Page | Route | Result |
|---|---|---|
app/page.js |
app/route.js |
❌ 충돌 발생 |
app/page.js |
app/api/route.js |
✅ 유효함 |
app/[user]/page.js |
app/api/route.js |
✅ 유효함 |
아래 코드는 Route Handlers를 사용해서 데이터베이스로부터 데이터를 가져오는 간단한 예시 코드입니다.
// app/api/posts/route.ts
export async function GET(request: Request) {
// 데이터베이스로부터 posts 데이터 가져오기
const posts = await db.query.posts.findMany({ ... });
// 응답 반환
return Response.json(posts);
}
Route Handlers는 HTTP 메서드 중에서 GET, POST, PUT, PATCH, DELETE, HEAD, 그리고 OPTIONS에 대한 요청을 처리할 수 있으며, 그 외에는 405 (Method Not Allowed) 응답을 하게 됩니다. 아래 코드는 다양한 HTTP 메서드를 사용하는 route.ts 파일 작성 예시를 나타낸 것입니다. 이 코드에서 볼 수 있듯이 export하는 함수의 이름을 HTTP 메서드 이름으로 작성하면 됩니다.
// app/api/route.ts
export async function GET(request: Request) {}
export async function POST(request: Request) {}
export async function PUT(request: Request) {}
export async function PATCH(request: Request) {}
export async function DELETE(request: Request) {}
export async function HEAD(request: Request) {}
export async function OPTIONS(request: Request) {}
또한 기존에 웹에서 제공하는 Request와 Response를 확장한 NextRequest 와 NextResponse 를 활용하면, 여러가지 부가적인 상황에 필요한 기능들을 편리하게 함수 형태로 호출해서 사용할 수 있습니다. 아래 코드는 NextRequest와 NextResponse를 사용한 예시 코드입니다.
// app/api/posts/route.ts
import { NextRequest, NextResponse } from 'next';
export async function GET(request: NextRequest) {
// request로부터 search params 가져오기
const searchParams = request.nextUrl.searchParams;
const offset = searchParams.get('offset');
const limit = searchParams.get('limit');
// 데이터베이스로부터 posts 데이터 일부 가져오기
const posts = await db.query.posts.findMany({
...
offset,
limit,
});
// 응답 반환
return NextResponse.json(posts);
}
참고로 Route Handlers는 기본적으로 캐싱되지 않습니다. 하지만, GET 메서드에 대해서는 캐싱을 선택적으로 적용할 수 있습니다. GET 메서드를 캐싱하려면 아래 코드와 같이 Route Handler 파일에 export const dynamic = 'force-static'과 같은 Route 설정 옵션을 사용하면 됩니다.
// app/api/route.ts
export const dynamic = 'force-static';
export async function GET() {
const res = await fetch('https://data.mongodb-api.com/...', {
headers: {
'Content-Type': 'application/json',
'API-Key': process.env.DATA_API_KEY,
},
});
const data = await res.json();
return Response.json({ data });
}
그리고 sitemap.ts, opengraph-image.tsx, icon.tsx와 같은 특수 Route Handlers 및 기타 메타데이터 파일은 동적 API나 동적 구성 옵션을 사용하지 않는 한 기본적으로 정적인 상태로 유지됩니다.
마지막 업데이트: 2025년 10월 24일 02시 17분
이 문서의 저작권은 이인제(소플)에 있습니다. 무단 전재와 무단 복제를 금합니다.
On this page