server/api 디렉터리로 만드는 백엔드, Nitro 엔진과 이벤트 핸들러.
서버 라우트와 Nitro API
Nuxt는 프런트엔드만의 도구가 아닙니다. 내장된 Nitro 서버 엔진 덕분에 별도 백엔드 없이도 API를 만들 수 있습니다. server/ 폴더에 파일을 두면 그대로 엔드포인트가 됩니다. 이번 레슨에서는 API 라우트, 쿼리·바디 읽기, 동적 라우트, 서버 미들웨어를 다룹니다.
학습 목표
server/api폴더가 어떻게 엔드포인트가 되는지 이해한다.defineEventHandler로 핸들러를 작성한다.- 쿼리스트링과 요청 바디를 읽는다.
- 동적 API 라우트와 서버 미들웨어를 만든다.
server 폴더 구조
server/ 안의 위치에 따라 역할이 정해집니다.
server/
├── api/ # /api/* 엔드포인트
│ └── tasks.ts → /api/tasks
├── routes/ # /* 임의 경로 (api 접두사 없음)
│ └── sitemap.xml.ts
└── middleware/ # 모든 요청 전에 실행
└── auth.ts
server/api/ 안의 파일은 자동으로 /api/ 접두사가 붙습니다.
첫 API 라우트
핸들러는 defineEventHandler 로 감싸고, 반환값이 곧 JSON 응답이 됩니다.
// server/api/tasks.ts
export default defineEventHandler(() => {
return [
{ id: 1, title: '강좌 작성' },
{ id: 2, title: '코드 리뷰' },
];
});
이제 브라우저나 useFetch('/api/tasks') 로 이 데이터를 받을 수 있습니다.
💡 TIP — 객체나 배열을 반환하면 Nitro가 알아서
Content-Type: application/json으로 직렬화해 줍니다.
HTTP 메서드 분기
파일명에 .get / .post 같은 접미사를 붙이면 메서드별 핸들러가 됩니다.
server/api/
├── tasks.get.ts → GET /api/tasks
└── tasks.post.ts → POST /api/tasks
쿼리와 바디 읽기
요청에서 데이터를 꺼낼 때는 event 를 받아 헬퍼 함수를 씁니다.
// server/api/tasks.get.ts — 쿼리스트링 읽기
export default defineEventHandler((event) => {
const query = getQuery(event); // /api/tasks?page=2 → { page: '2' }
const page = Number(query.page ?? 1);
return { page };
});
// server/api/tasks.post.ts — 요청 바디 읽기
export default defineEventHandler(async (event) => {
const body = await readBody(event); // { title: '...' }
// ...DB 저장 로직...
return { ok: true, created: body };
});
| 헬퍼 | 용도 |
|---|---|
getQuery(event) | 쿼리스트링 객체 |
readBody(event) | 요청 바디(주로 POST/PUT) |
getRouterParam(event, 'id') | 동적 라우트 파라미터 |
setResponseStatus(event, 404) | 상태 코드 설정 |
createError(...) | 에러 응답 던지기 |
동적 API 라우트
페이지 라우팅처럼 대괄호로 동적 세그먼트를 만듭니다.
// server/api/tasks/[id].get.ts → /api/tasks/42
export default defineEventHandler((event) => {
const id = getRouterParam(event, 'id');
const task = findTask(Number(id));
if (!task) {
throw createError({ statusCode: 404, statusMessage: '일감을 찾을 수 없습니다' });
}
return task;
});
⚠️ 주의 — 에러는 직접 객체를 반환하지 말고
createError로 던지세요(throw). 그래야 상태 코드가 올바르게 설정되고 클라이언트의error로 잡힙니다.
서버 미들웨어
server/middleware/ 안의 파일은 모든 요청 전에 자동 실행됩니다. 인증 검사, 로깅 등에 씁니다. 값을 반환하지 않고 통과시키는 점이 API 핸들러와 다릅니다.
// server/middleware/log.ts
export default defineEventHandler((event) => {
console.log(`[${event.method}] ${event.path}`);
// 반환값 없음 → 다음 단계로 통과
});
// server/middleware/auth.ts
export default defineEventHandler((event) => {
if (event.path.startsWith('/api/admin')) {
const token = getHeader(event, 'authorization');
if (!token) {
throw createError({ statusCode: 401, statusMessage: '인증 필요' });
}
}
});
요약
server/api/의 파일은 자동으로/api/*엔드포인트가 됩니다.- 핸들러는
defineEventHandler로 감싸고 반환값이 JSON 응답이 됩니다. getQuery·readBody·getRouterParam으로 입력을 읽습니다.server/middleware/는 모든 요청 전에 실행되어 인증·로깅에 쓰입니다.
연습문제
server/api/hello.ts를 만들어{ message: '안녕하세요' }를 반환하고 브라우저에서 확인해 보세요.tasks.get.ts/tasks.post.ts로 GET·POST를 분리하고, POST에서readBody로 받은 제목을 되돌려 주세요.server/api/tasks/[id].get.ts를 만들어 없는 id에는 404 에러를createError로 던져 보세요.server/middleware/log.ts로 모든 요청의 메서드와 경로를 콘솔에 찍어 보세요.
힌트 — 메서드별 핸들러는 파일명에
.get/.post를 붙이고, 동적 값은getRouterParam으로 읽습니다.
💡 연습문제 풀이
불러오는 중…
댓글 0
“Nuxt.js” 강좌에 대한 댓글입니다.