[NextJS v14] NextJS API Routes란?

eeeyooon·2024년 4월 20일
2

[NextJS]

목록 보기
1/1
post-thumbnail

NextJS API Routes


🌼 해당 글은 다음 스펙을 기준으로 작성되었습니다.

  • NextJS v14.1.0
  • pages router
  • typescript

NextJS 공식 문서(pages router) - API Routes

들어가기에 앞서, 공식문서에도 나와있듯이 만약 App Router를 사용한다면 API Routes 대신 Server ComponentsRoute Handlers를 사용할 수 있다. 해당 포스팅은 pages router에서의 API Routes 공식 문서를 바탕으로 작성할 예정이다.



API Routes


API Routes란 쉽게 말하면 NextJS에서 제공하는 NextJS 앱 내에서 API를 만들 수 있게 해주는 기능이다. pages/api 폴더 내의 모든 파일은 /api/*에 대응되며, page가 아닌 API 엔드포인트로 취급된다. 이는 서버 사이드 번들이며, 클라이언트 사이드 번들 크기를 증가시키지 않는다.


pages/api/hello.ts

import type { NextApiRequest, NextApiResponse } from 'next'
 
type ResponseData = {
  message: string
}
 
export default function handler(
  req: NextApiRequest,
  res: NextApiResponse<ResponseData>
) {
  res.status(200).json({ message: 'Hello from Next.js!' })
}

이 API 라우트 pages/api/hello.ts는 상태코드 200을 가진 json 응답을 반환한다. API 라우트가 동작하려면 다음과 같은 매개변수를 받는 함수를 default로 내보내야 한다. (일명 요청 핸들러)



HTTP Methods

API 라우트에서 다른 HTTP 메서드를 처리하려면, 요청 핸들러에서 req.method를 사용하면 된다.

import type { NextApiRequest, NextApiResponse } from 'next'
 
export default function handler(req: NextApiRequest, res: NextApiResponse) {
  if (req.method === 'POST') {
    // POST 요청 처리
  } else {
    // 다른 HTTP 메서드 처리
  }
}



Reqeust Helpers

API 라우트는 들어오는 요청(req)을 파싱하는 내장 요청 헬퍼를 제공한다.

  • req.cookies - 요청에 따라 전송된 쿠키를 포함하는 객체. 기본 값은 {}
  • req.query - 쿼리 문자열을 포함하는 객체. 기본 값은 {}
  • req.body - content-type에 따라 분석된 body를 포함하는 객체, 또는 body가 전송되지 않은 경우 null



Response Helpers

res(서버 응답 객체)는 DX를 향상하고 새로운 API 엔드포인트를 빠르게 생성하는 데 도움을 주기 위해 Express.js와 유사한 여러 헬퍼 함수를 포함하고 있다.

  • res.status(code) - 상태 코드를 설정하는 함수. code는 유효한 HTTP 상태 코드여야 한다.
  • res.json(body) - JSON 응답을 보낸다. body직렬화할 수 있는 객체여야 한다.
  • res.redirect([status,] path) - 지정된 경로 또는 URL로 리다이렉트한다. status는 유효한 HTTP 상태 코드여야 한다. 지정하지 않는다면 status의 기본 값은 "307", 즉 "임시 다이렉트(Temporary redirect)"이다.
  • res.revalidate(urlPath) - getStaticProps를 사용하여 요청 시 페이지 재검증을 수행한다. urlPathstring이어야 한다.



응답 상태코드 설정하기

응답을 클라이언트에게 보낼 때, 응답 상태 코드를 설정할 수 있다. 다음 예시는 응답의 상태코드를 200(OK)으로 설정하고, Hello from Next.js! 값을 가진 message 프로퍼티를 JSON 응답으로 반환한다.

import type { NextApiRequest, NextApiResponse } from 'next'
 
type ResponseData = {
  message: string
}
 
export default function handler(
  req: NextApiRequest,
  res: NextApiResponse<ResponseData>
) {
  res.status(200).json({ message: 'Hello from Next.js!' })
}



지정된 경로 또는 URL로 리다이렉트하기

예를 들어 form을 사용할 경우, 클라이언트가 form을 제출하면 지정된 경로 또는 URL로 리다이렉트할 수 있다.

다음 예시는 form을 성공적으로 제출하면 클라이언트를 /로 리다이렉트하는 코드이다.

import type { NextApiRequest, NextApiResponse } from 'next'
 
export default async function handler(
  req: NextApiRequest,
  res: NextApiResponse
) {
  const { name, message } = req.body
 
  try {
    await handleFormInputAsync({ name, message })
    res.redirect(307, '/')
  } catch (err) {
    res.status(500).send({ error: 'Failed to fetch data' })
  }
}



동적 API 라우트

API 라우트는 동적 라우트를 지원하며 pages에 사용되는 파일 이름 규칙을 따른다. 예를 들어 API 라우트 pages/api/post/[pid].js에 다음 코드가 있다.

import type { NextApiRequest, NextApiResponse } from 'next'
 
export default function handler(req: NextApiRequest, res: NextApiResponse) {
  const { pid } = req.query
  res.end(`Post: ${pid}`)
}

/api/post/abc로의 요청은 텍스트 Post: abc를 응답으로 받게 된다.



API Routes 활용 예시

나는 프로젝트에서 JWT를 HttpOnly 쿠키에 전달하기 위해 API Routes를 사용했었다. (참고)
쿠키에 있는 JWT의 여부를 가지고 로그인 상태를 확인했기 때문에 사용자가 로그아웃을 선택하면 쿠키에 있는 JWT를 제거해야 했다. 그 때 사용한 로그아웃 API 라우트는 다음과 같다.


/pages/api/auth/logout.ts

import { NextApiRequest, NextApiResponse } from 'next';
import { deleteCookie } from 'cookies-next';

export default function logout(req: NextApiRequest, res: NextApiResponse) {
  if (req.method === 'POST') {
    deleteCookie('accessToken', { req, res, path: '/' });
    deleteCookie('refreshToken', { req, res, path: '/' });

    res.status(200).json({ message: '로그아웃 성공 | 토큰 삭제' });
  } else {
    res.setHeader('Allow', ['POST']);
    res.status(405).end(`Method ${req.method} Not Allowed`);
  }

POST 요청일 때만 실행되도록 하였고, 만약 POST가 아닌 다른 HTTP Method 요청이 들어왔다면 405 상태코드와 Method ${req.method} Not Allowed를 응답으로 보냈다.
logout API 라우트로 POST 요청이 왔을 때 쿠키에 있는 accessTokenrefreshToken을 제거하였고, 상태코드 200을 가진 json을 응답으로 반환하였다.


다음은 해당 logout API 라우트에 요청을 보내는 코드이다.


  const handleLogout = () => {
    logoutApi()
      .then(() => {
        axios
          .post(
            '/api/auth/logout',
            {},
            {
              headers: {
                'Content-Type': 'application/json',
              },
            },
          )
          .then(() => {
            router
              .push({
                pathname: '/',
                query: { logout: true },
              })
          })
  };

로그아웃 버튼 클릭 시 handleLogout이 실행되도록 하였다. 가장 먼저 백엔드 서버에 로그아웃 요청(logoutApi())을 보내고, 백엔드 서버 로그아웃이 성공적으로 응답이 오면 내가 만든 logout API 라우트로 post 요청을 보내 쿠키에 있는 JWT를 제거하였다. 쿠키 제거까지 완료되면 /로 쿼리와 함께 리다이렉션하도록 처리하였다.




참고

Nextjs.kr - docs/routing/apiroutes

0개의 댓글