Nuxt 3의 server/api 폴더를 활용하여 서버 API를 구축하는 방법에 대해 정리한 문서입니다.
server/api 폴더
Nuxt 3에서는 server/api
폴더를 통해 서버 API를 간단하게 구현할 수 있습니다.
파일 기반 라우팅을 지원하기 때문에, 아래 처럼 구성하면 됩니다.
기본 구조
my-nuxt-project/
├── server/
│ ├── api/
│ │ ├── hello.ts # /api/hello
│ │ ├── users/
│ │ │ ├── [id].ts # /api/users/123
│ │ │ └── index.ts # /api/users
API 엔드포인트 작성하기
1. 기본 GET 요청 처리
// server/api/hello.ts
export default defineEventHandler((event) => {
return {
message: "Hello from Nuxt Server API!",
};
});
이제 /api/hello
로 GET 요청을 보내면 응답을 받을 수 있습니다.
localhost:3000/api/hello 에 접속하면 message가 출력된다.
// 클라이언트에서 사용
const { data } = await useFetch("/api/hello");
console.log(data.value.message); // 'Hello from Nuxt Server API!'
2. 동적 라우트 파라미터 처리
// server/api/users/[id].ts
export default defineEventHandler((event) => {
const id = getRouterParam(event, "id");
return {
id,
name: `User ${id}`,
createdAt: new Date(),
};
});
3. POST 요청 처리
// server/api/users/create.ts
export default defineEventHandler(async (event) => {
// POST 데이터 읽기
const body = await readBody(event);
// 유효성 검사
if (!body.name) {
throw createError({
statusCode: 400,
statusMessage: "Name is required",
});
}
return {
id: 1,
...body,
createdAt: new Date(),
};
});
클라이언트에서 사용:
const { data } = await useFetch("/api/users/create", {
method: "POST",
body: {
name: "John Doe",
email: "john@example.com",
},
});
4. 쿼리 파라미터 처리
// server/api/search.ts
export default defineEventHandler((event) => {
const query = getQuery(event);
return {
searchTerm: query.q,
page: query.page || 1,
};
});
미들웨어 활용하기
1. 인증 미들웨어
// server/middleware/auth.ts
export default defineEventHandler((event) => {
const token = getHeader(event, "authorization");
if (!token) {
throw createError({
statusCode: 401,
statusMessage: "Unauthorized",
});
}
});
2. CORS 설정
// server/middleware/cors.ts
export default defineEventHandler((event) => {
setResponseHeaders(event, {
"Access-Control-Allow-Methods": "GET,HEAD,PUT,PATCH,POST,DELETE",
"Access-Control-Allow-Origin": "*",
});
if (getMethod(event) === "OPTIONS") {
event.node.res.statusCode = 204;
event.node.res.end();
}
});
에러 처리
// server/api/items/[id].ts
export default defineEventHandler(async (event) => {
const id = getRouterParam(event, "id");
// 데이터베이스 조회 시뮬레이션
const item = await findItem(id);
if (!item) {
throw createError({
statusCode: 404,
statusMessage: `Item ${id} not found`,
data: {
id,
},
});
}
return item;
});
환경 변수 활용
// server/api/config.ts
export default defineEventHandler((event) => {
const config = useRuntimeConfig();
return {
apiVersion: config.public.apiVersion,
mode: config.public.mode,
};
});
nuxt.config.ts 설정:
export default defineNuxtConfig({
runtimeConfig: {
// 프라이빗 키 (서버에서만 사용)
apiSecret: process.env.API_SECRET,
// 퍼블릭 키 (클라이언트에서도 사용 가능)
public: {
apiVersion: "1.0.0",
mode: process.env.NODE_ENV,
},
},
});
실제 활용 예시
데이터베이스 연동
// server/api/posts/index.ts
import { PrismaClient } from "@prisma/client";
const prisma = new PrismaClient();
export default defineEventHandler(async (event) => {
const method = getMethod(event);
switch (method) {
case "GET":
return await prisma.post.findMany();
case "POST":
const body = await readBody(event);
return await prisma.post.create({
data: body,
});
default:
throw createError({
statusCode: 405,
statusMessage: "Method not allowed",
});
}
});
핵심 정리
Server API 정리
라우팅 규칙
server/api/
디렉토리의 파일 이름이 URL 경로로 매핑됩니다.server/api/hello.js
→ /api/hello.server/api/users/[id].js
→ /api/users/:id.
핸들러 이벤트
defineEventHandler
로 요청 및 응답 처리.readBody
: 요청 본문(JSON 데이터) 읽기.getQuery
: 쿼리 문자열 읽기.setResponseStatus
: 응답 상태 코드 설정.
위의 핵심 부분만 잘 이해하면 충분히 활용 가능할 듯 합니다.
현재 진행 중인 wallert 앱의 데이터 관리를 위해 어드민 페이지를 제작 중인데요. Nuxt의 Server Api 기능을 활용하여 간단하게 구현 중입니다.