dev.syw

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/ 는 모든 요청 전에 실행되어 인증·로깅에 쓰입니다.

연습문제

  1. server/api/hello.ts 를 만들어 { message: '안녕하세요' } 를 반환하고 브라우저에서 확인해 보세요.
  2. tasks.get.ts / tasks.post.ts 로 GET·POST를 분리하고, POST에서 readBody 로 받은 제목을 되돌려 주세요.
  3. server/api/tasks/[id].get.ts 를 만들어 없는 id에는 404 에러를 createError 로 던져 보세요.
  4. server/middleware/log.ts 로 모든 요청의 메서드와 경로를 콘솔에 찍어 보세요.

힌트 — 메서드별 핸들러는 파일명에 .get / .post 를 붙이고, 동적 값은 getRouterParam 으로 읽습니다.

💡 연습문제 풀이

불러오는 중…

함께 보면 좋은 자료

댓글 0

Nuxt.js” 강좌에 대한 댓글입니다.

댓글을 작성하려면 로그인이 필요합니다.