본문 바로가기

Next.js9

Next.js - API 만들기 (API Routes)

이제 클라이언트 쪽은 알겠는데, API는 어떻게 만들까?

Next.js에서 함수 하나로 API를 만들 수 있어! 

언제든지 Serverless로 전환하기 쉬운 구조야.

Photo by  Tianyi Ma  on  Unsplash

'pages/api' 디렉토리에다가 함수하나만 만들면 끝! 쉽지?

// req = 요청데이터, res = 응답 데이터

export default (req, res) => {
  if (req.method === 'POST') {
    // POST 요청에 대한 처리
  } else {
    // 나머지 메서드에 대한 처리
  }
}

끝! 소름!

배포에서 이야기 하겠지만 옵션에 따라 서버리스 함수로 배포될수도 있어 ㄷ ㄷ ㄷ

예제하나 만들어볼까?

hello.js라는 파일을 pages/api디렉토리 아래에 만들고, 아래 코드를 작성하자!

export default (req, res) => {
  res.status(200).json({ text: 'Hello' })
}

http://localhost:3000/api/hello

접속하면 위에 정의한 json 나오는거 보여? ㅎ

{
  "text": "Hello"
}

req 는  http.IncomingMessage, res는 http.ServerResponse의 인스턴스야 참고해!

 

여기서 잠깐!

우리 보통 RESTful 형식으로 API 만들잖아?

RESTful API만들기

보통 RESTful한 api다라고 하면 대표적으로 아래와 같아.

  • api/posts/ 을 GET으로 호출하면 블로그 글들의 리스트가 내려오고
  • api/posts/5355 와 같은 형식으로 호출하면, 글 아이디값이 5355인 글의 api 결과가 리턴 될꺼야

두가지 방식으로 구현할 수 있지.

첫번째 방법

/api/posts.js
/api/posts/[postId].js

두번째 방법

/api/posts/index.js
/api/posts/[postId].js

두가지 방법 모두 리스트가 내려올지, 글 하나가 내려올지 코드를 완전 구분해서 쓸수 있어서 나중에 Serverless 형태로 가기에도 완전 좋은 구조야.

이외에도 여러가지 방법이 있어. 

하위 경로를 전부 포함하기

위에서 'api/post/5355' URL 하나에만 매칭되었다면 'api/post/5355/reply', 'api/post/5355/reply/1' 와 같이 여러 depth에 걸친 URL을 함께 다룰수도 있어.

방법은 바로 파일명에 '...' 을 붙이면 돼

요렇게 -> 'pages/api/post/[...multiIds].js

그러면 '/api/post/a', '/api/post/a/b', '/api/post/a/b/c'와 같은 경로가 전부 매칭됨.

만약 '/api/post/a' url이 매칭되면 req객체의 query 에 아래와 같이 들어가 있지.

{ "multiIds": ["a"] }

URL이 '/api/post/a/b/c' 인경우

{ "multiIds": ["a", "b", "c"] }

샘플 코드 하나 볼까?

export default (req, res) => {
  const {
    query: { multiIds },
  } = req

  res.end(`Post: ${multiIds.join(', ')}`)
}

 

리턴값은 "Post: a, b, c"

상위경로 포함하기

별로 추천하지는 않지만 '/api/post/', '/api/post/a' 두개 경로를 한꺼번에 다룰수 있기는 해

방법은 파일명에 꺽쇄 두개쓰기!

'pages/api/post/[[...multiIds]].js'

query값에는 아래처럼 들어가 있을 꺼야

{ } // `/api/post` 빈 객체
{ "multiIds": ["a"] } // `/api/post/a` 
{ "multiIds": ["a", "b"] } // `GET /api/post/a/b` 

샘플코드 선물!

export default (req, res) => {
  const {
    query: { ids },
  } = req 

  if(ids) {
    res.end(`Post: ${ids.join(', ')}`)
  } else {
    res.end("no ids")
  }
}

 

어때?

이제 API도 마음껏 작성할수 있겠지?