route.ts 로 API 엔드포인트를 만든다.
라우트 핸들러 (API)
페이지뿐 아니라 API 엔드포인트도 App Router 안에서 만들 수 있습니다. route.ts 파일에 HTTP 메서드 이름의 함수를 내보내면 그게 곧 API가 됩니다. 웹 표준 Request/Response 를 그대로 쓰는 것이 특징입니다.
학습 목표
route.ts로 API 엔드포인트를 만든다.GET,POST등 메서드별 핸들러를 작성한다.- 표준
Request/Response와NextResponse를 사용한다. - 동적 세그먼트, 쿼리 파라미터, 요청 바디를 읽는다.
첫 라우트 핸들러
app/api/.../route.ts 에 메서드 함수를 내보냅니다. page.tsx 와 route.ts 는 같은 폴더에 함께 둘 수 없습니다.
app/
└── api/
└── hello/
└── route.ts → /api/hello
// app/api/hello/route.ts
import { NextResponse } from 'next/server';
export async function GET() {
return NextResponse.json({ message: '안녕하세요' });
}
/api/hello 로 요청하면 JSON이 응답됩니다. NextResponse.json() 은 Content-Type 까지 알아서 붙여 줍니다.
메서드별 핸들러
함수 이름이 곧 HTTP 메서드입니다. GET, POST, PUT, PATCH, DELETE 등을 같은 파일에 함께 둘 수 있습니다.
// app/api/posts/route.ts
import { NextResponse } from 'next/server';
export async function GET() {
const posts = await getPosts();
return NextResponse.json(posts);
}
export async function POST(request: Request) {
const body = await request.json(); // 요청 바디 읽기
const created = await createPost(body);
return NextResponse.json(created, { status: 201 });
}
💡 TIP — 정의하지 않은 메서드로 요청이 오면 Next.js가 자동으로
405 Method Not Allowed를 응답합니다.
쿼리 파라미터 읽기
URL의 ?key=value 는 request.nextUrl.searchParams 또는 표준 URL 로 읽습니다.
// app/api/search/route.ts → /api/search?q=next
import { NextRequest, NextResponse } from 'next/server';
export async function GET(request: NextRequest) {
const q = request.nextUrl.searchParams.get('q') ?? '';
const results = await search(q);
return NextResponse.json(results);
}
동적 세그먼트
페이지처럼 [id] 폴더로 동적 경로를 만들 수 있습니다. 두 번째 인자의 params(Promise)로 값을 받습니다.
// app/api/users/[id]/route.ts → /api/users/42
import { NextResponse } from 'next/server';
export async function GET(
_request: Request,
{ params }: { params: Promise<{ id: string }> },
) {
const { id } = await params;
const user = await getUser(id);
if (!user) {
return NextResponse.json({ error: '없음' }, { status: 404 });
}
return NextResponse.json(user);
}
상태 코드와 헤더
NextResponse.json(data, options) 의 두 번째 인자로 상태 코드와 헤더를 지정합니다.
return NextResponse.json(
{ ok: true },
{
status: 200,
headers: { 'Cache-Control': 'no-store' },
},
);
⚠️ 주의 — 라우트 핸들러는 기본적으로 캐시되지 않지만, 단순
GET은 조건에 따라 캐시될 수 있습니다. 항상 최신 응답이 필요하면Cache-Control: no-store를 명시하거나export const dynamic = 'force-dynamic'을 두세요.
요약
route.ts에GET/POST등 메서드 함수를 내보내면 API가 된다.- 웹 표준
Request와NextResponse를 사용한다. - 쿼리는
searchParams, 바디는await request.json()으로 읽는다. - 동적 세그먼트
[id]는params(Promise)로 받는다.
연습문제
/api/time을 만들어 현재 시각을 JSON으로 반환하세요./api/echo에POST로 받은 바디를 그대로 되돌려 주는 핸들러를 작성하세요./api/users/[id]에서 없는 id면 404를 응답하도록 만들어 보세요./api/search?q=...에서 쿼리q를 읽어 필터링한 결과를 반환하세요.
힌트 — 바디는
await request.json(), 쿼리는request.nextUrl.searchParams.get('q')로 읽습니다. 상태 코드는NextResponse.json(data, { status: 404 })로 지정합니다.
💡 연습문제 풀이
불러오는 중…
댓글 0
“Next.js” 강좌에 대한 댓글입니다.