Route Handlers를 사용하면, 특정 경로에 대한 사용자 정의 Next Server API를 생성할 수 있다. 웹 요청인 Request와 Response API로 이를 구현하며, app 디렉토리 내에서만 사용할 수 있다. 만약 app/api/example/route.ts안에 Route Handler 함수를 생성한다면, '/api/example'이 Next Server API의 주소가 된다. 참고로, Route Handler는 RRequest Memoization를 할 수 없다.
Best Practices
// app/api/example/route.ts
import { NextRequest, NextResponse } from 'next/server';
// 외부 API 기본 URL
const BASE_URL = 'https://api.example.com/v1/resource';
// GET 요청 처리: 데이터 목록 가져오기
export async function GET(req: NextRequest) {
try {
const response = await fetch(BASE_URL, {
method: 'GET',
headers: {
'Content-Type': 'application/json',
},
});
// 백엔드 서버 응답 실패
if (!response.ok) {
const errorData = await response.json();
return NextResponse.json(errorData, { status: response.status });
}
// 백엔드 서버 응답 성공
const data = await response.json();
return NextResponse.json(data, { status: response.status });
} catch (error) {
// 예기치 못한 예외나 네트워크 문제 발생
return NextResponse.json(
{ message: 'Unexpected error occurred', detail: (error as Error).message },
{ status: 500 }
);
}
}
// POST 요청 처리: 새 데이터 추가
export async function POST(req: NextRequest) {
try {
const body = await req.json();
const response = await fetch(BASE_URL, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(body),
});
// 백엔드 서버 응답 실패
if (!response.ok) {
const errorData = await response.json();
return NextResponse.json(errorData, { status: response.status });
}
// 백엔드 서버 응답 성공
const data = await response.json();
return NextResponse.json(data, { status: response.status });
} catch (error) {
// 예기치 못한 예외나 네트워크 문제 발생
return NextResponse.json(
{ error: 'Unexpected error occurred', details: (error as Error).message },
{ status: 500 }
);
}
}
// PUT 요청 처리: 데이터 업데이트
export async function PUT(req: NextRequest) {
try {
const body = await req.json();
const { id, ...updates } = body;
const response = await fetch(`${BASE_URL}/${id}`, {
method: 'PUT',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(updates),
});
// 백엔드 서버 응답 실패
if (!response.ok) {
const errorData = await response.json();
return NextResponse.json(errorData, { status: response.status });
}
// 백엔드 서버 응답 성공
const data = await response.json();
return NextResponse.json(data, { status: response.status });
} catch (error) {
// 예기치 못한 예외나 네트워크 문제 발생
return NextResponse.json(
{ error: 'Unexpected error occurred', details: (error as Error).message },
{ status: 500 }
);
}
}
// DELETE 요청 처리: 데이터 삭제
export async function DELETE(req: NextRequest) {
try {
// 쿼리 문자열 추출
const { searchParams } = new URL(req.url);
const id = searchParams.get('id');
// 클라이언트 에러 발생
if (!id) {
return NextResponse.json({ error: 'ID is required' }, { status: 400 });
}
const response = await fetch(`${BASE_URL}/${id}`, {
method: 'DELETE',
headers: {
'Content-Type': 'application/json',
},
});
// 백엔드 서버 응답 실패
if (!response.ok) {
const errorData = await response.json();
return NextResponse.json(errorData, { status: response.status });
}
// 백엔드 서버 응답 성공
const data = await response.json();
return NextResponse.json(data, { status: response.status });
} catch (error) {
// 예기치 못한 예외나 네트워크 문제 발생
return NextResponse.json(
{ error: 'Unexpected error occurred', details: (error as Error).message },
{ status: 500 }
);
}
}
import axios from 'axios';
// 외부 API 기본 URL
const BASE_URL = 'http://localhost:3000';
// Axios 인스턴스 생성 (공통 설정 적용 가능)
const axiosInstance = axios.create({
baseURL: BASE_URL,
headers: {
'Content-Type': 'application/json',
},
});
// GET 요청: 데이터 목록 가져오기
const fetchExampleData = async () => {
const response = await axiosInstance.get('/api/example');
if (response.status === 200) return response.data;
else throw response.data.code;
};
// POST 요청: 데이터 추가
const createExampleData = async (newItem) => {
const response = await axiosInstance.post('/api/example', newItem);
if (response.status === 200) return response.data;
else throw response.data.code;
};
// PUT 요청: 데이터 업데이트
const updateExampleData = async ({ id, updates }) => {
const response = await axiosInstance.put('/api/example', { id, ...updates });
if (response.status === 200) return response.data;
else throw response.data.code;
};
// DELETE 요청: 데이터 삭제
const deleteExampleData = async (id: string) => {
const response = await axiosInstance.delete(`/api/example?id=${id}`);
if (response.status === 200) return response.data;
else throw response.data.code;
};