티스토리 뷰

API란?

Application Programming Interface의 약자로, 응용 프로그래밍 인터페이스라고 해석할 수 있습니다. 쉽게 말해, 컴퓨터나 컴퓨터 프로그램 사이의 연결을 의미합니다. 즉, 연결을 어떻게 할 것인가에 대한 정의라고 보면 되겠습니다.

Frontend Service - Backend Service 간의 연결

Frontend가 만드는 영역을 Frontend Service, Backend가 만드는 영역을 Backend Service라고 하겠습니다.

이 두 가지가 서로 연결될 때 API가 활용됩니다.

 

Frontend Service는 고객과 닿아있고, Backend Service는 DB에 닿아있습니다.

고객이 DB에 접근하기 위해 FE와 BE가 연결되어야 하고, 이때 API를 활용합니다.

BE가 제공해주는 API를 통해 DB의 내용을 활용할 수 있습니다.

실제 서비스 예시

예를 들어 커머스 같은 사이트에 들어가서 개발자 도구를 열고 네트워크 탭을 열어보면 어떤 API를 통해 FE와 BE가 통신하는 지 살펴볼 수 있습니다.

위 네트워크 창에서 보이는 것처럼 많은 내용을 API를 통해 통신하고 있음을 알 수 있었습니다.

Next.js가 제공하는 API Routes - pages/api/*

우선 src / pages / api 라는 폴더를 생성합시다. 저는 예제를 위해 user.js라는 파일도 생성했습니다.

src/pages/api/user.js 생성

만들었으면 다음 내용을 우선 채워봅시다.

 

📜 src/pages/api/user.js 파일

1
2
3
4
5
export default function handler(req, res) {
  // 이름을 handler로 해줘야 합니다.
  res.status(200).json({ name'doeunnkimm' });
}
 
cs

위 코드대로 handler를 api/user.js에 둡니다.

 

📜 src/pages/[username]/[info].js 파일

여기에서 Client Data Fetching으로 한번 조회를 해보겠습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
import Layout from 'components/Layout';
import SubLayout from 'components/SubLayout';
import { useRouter } from 'next/router';
import { useEffect, useState } from 'react';
 
export default function UsernameInfo() {
  const router = useRouter();
  const { username, info } = router.query;
  const [name, setName] = useState('');
 
  useEffect(() => {
    fetch('/api/user')
      .then(res => res.json())
      .then(data => {
        setName(data.name);
      });
  }, []);
  return (
    <>
      <h2>
        UsernameInfo 🌱 {username}'s {info}
      </h2>
      <h2>Name: {name}</h2>
    </>
  );
}
 
UsernameInfo.getLayout = function getLayout(page) {
  return (
    <Layout>
      <SubLayout>{page}</SubLayout>
    </Layout>
  );
};
cs

실행 화면

보시면 [username]/[info]여서 url에 입력한 대로 doeunnkimm과 name이 보여졌고,

아래 Name: 다음으로 온 내용은 api를 통해 온 것인데요. 그렇다면 개발자 도구에서 네트워크 을 열어 확인해 볼까요?

요청

확인해 보면 실제로 /api/user로 호출을 했으며 응답값으로는 아래와 같이 온 것을 확인할 수 있었습니다.

응답

이런 식이라면 src/pages/api 폴더 속 파일에서 데이터 베이스의 실제 값을 꺼내온다 하는 코드를 작성할 수 있을 거 같죠?

 

예시를 위해 src/constants 라는 이름으로 고정값들을 저장할 폴더를 하나 만들어 줍시다.

 

📜 src/constants/userDetail.js 파일

1
2
3
4
5
6
export const userDetail = {
  name'doeunnkimm',
  age: 23,
  height: '2m',
  weight: '20kg',
};
cs

 

📜 src/pages/api/user.js 파일

1
2
3
4
5
6
import { userDetail } from 'constants/userDetail';
 
export default function handler(req, res) {
  // 이름을 handler로 해줘야 합니다.
  res.status(200).json(userDetail);
}
cs

위에서 만들었던 객체를 그대로 넘겨주는 것입니다.

실행 화면

Dynamic API Routes

우리는 이전에 페이지 기반으로 dynamic한 동작을 했었는데요.API Routes에서도 가능합니다.

 

📜 src/pages/api/user-info/[uid].js 파일

1
2
3
4
export default function handler(req, res) {
  const { uid } = req.query;
  res.status(200).json({ name: `doeunnkimm - ${uid}` });
}
cs

 

이번에는 req.query를 통해 uid를 받았습니다. 즉, 응답값 안에 있는 uid를 추출한 것인데요.

 

📜 src/pages/[username]/[info].js 파일

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
import Layout from 'components/Layout';
import SubLayout from 'components/SubLayout';
import { useRouter } from 'next/router';
import { useEffect, useState } from 'react';
 
export default function UsernameInfo() {
  const router = useRouter();
  const { username, info, uid } = router.query;
  const [name, setName] = useState('');
 
  useEffect(() => {
    if (uid !== null) {
      fetch(`/api/user-info/${uid}`)
        .then(res => res.json())
        .then(data => {
          setName(data.name);
        });
    }
  }, [uid]);
 
  return (
    <>
      <h2>
        UsernameInfo 🌱 {username}'s {info}
      </h2>
      <h2>Name: {name}</h2>
    </>
  );
}
 
UsernameInfo.getLayout = function getLayout(page) {
  return (
    <Layout>
      <SubLayout>{page}</SubLayout>
    </Layout>
  );
};
 
cs

코드를 보시게 되면, 우선 router.query를 통해 uid를 받고 있습니다. 그말은 지금 username과 info는 slug를 통해 사용되는 것이므로 우리가 파일 시스템을 통해 정해 놓았던 /[username]/[info] 자리의 값들입니다.

 

그렇지만 uid는 우리가 파일 시스템을 통해 정해놓은 것은 아니므로, 정말 query를 통해 들어오는 값임을 알 수 있습니다. 예를 들어 ?query=1 처럼 말이죠 !

이 말을 통해 우리가 위에서 uid를 어쨌든 무슨 방법을 통해서 uid를 가지고 요청을 보내야하는 것으로 예상이 되는데 이때 우리는 uid를 query를 통해 보내고 그걸 잡아서 api 요청을 보낸다고까지 코드를 통해 예상할 수 있을 겁니다.

 

그럼 우선 uid 값을 알았다고 합시다! 그러면 이제 그 값을 요청값으로 서버에게 보내야겠죠?

왜냐하면 우리가 아까 api/[uid].js 에서 const uid = req.query라고 했기 때문입니다.

 

그런데 마찬가지로 우리는 api에서 [uid] 즉, slug를 통해 uid를 받고 있기 때문에 이 또한 여기에서 query는 ?uid=1 이 아닌 /1을 의미하게 되는 것입니다.

 

여기까지라면 우선, 클라이언트는 어떤 URL을 통해 요청을 보내야하냐? 하면 → /[username]/[info]?uid=1

이제 uid 값을 알았으니 요청을 보낸다 어디로? → /api/user-info/[uid]

 

URL을 잘 봐주세요
URL을 잘 봐주세요

Routing에서 다뤘던 여러 Slug 활용법 적용 가능

slug를 통해 다중 Route도 가능하며 /api/get/create.js 처럼 여러 depth를 두는 것도 가능합니다.

API Middlewares

API 요청에서는 단순히 요청과 응답만 받는 것이 아니라, 미들웨어를 통해 좀 더 확장한 기능을 사용할 수 있습니다.

우선, 내장 Middleare의 기능에는 대표적으로, req.cookies, req/query, ... 가 있습니다.

 

우리가 아까 api/[slug].js에서 요청값에 있는 query를 꺼낸 것도 모두 미들웨어 덕분이라는 말로 이어지겠습니다.

 

아까 해보지 않았던 쿠키값을 이용하는 것을 해볼까요?

 

📜 src/api/user-info/[uid].js 파일

1
2
3
4
5
6
7
export default function handler(req, res) {
  const { uid } = req.query;
  const cookies = req.cookies;
  res
    .status(200)
    .json({ name: `doeunnkimm - ${uid}, ${JSON.stringify(cookies)}` });
}
cs

임의로 쿠키 삽입하고 확인해보겠습니다.
실행 화면

이 외에도 다양한 미들웨어들을 활용할 수 있는데요. 대표적인 예를 들어 보면, CORS 이슈들에 대항할 수 있는 미들웨어들을 추가해서 api를 구성할 수 있기도 합니다.

Response

아까 요청에 대한 응답으로 res. 하고 적었던 내용 기억하시나요? 아까와는 조금 다르게 응답값을 줘 보겠습니다.

 

📜 src/api/user-info/[uid].js 파일

1
2
3
4
5
6
export default function handler(req, res) {
  const { uid } = req.query;
  const cookies = req.cookies;
 
  res.status(500).send({ error: 'error' });
}
cs

위와 같이 해보고 화면을 확인해 볼까요? 화면에는 요청값이 나오지 않고, 네트워크 탭에 가보면 500에러라면서 빨간색 불이 들어온 것을 확인하실 수 있는데요.즉, 원하는 에러를 보낼 수 있다는 말이죠 !

 

또 다른 것도 해볼까요?

1
2
3
4
5
6
export default function handler(req, res) {
  const { uid } = req.query;
  const cookies = req.cookies;
 
  res.redirect(307'/api/user');
}
cs

이번에는 /api/user-info/[uid]로 요청이 오면 응답으로 /api/user로 리다이렉트 시키겠다고 하고 있습니다.

즉, 이 요청 URL로 요청이 오게 되면 /api/user로 돌려보내겠다! /api/user에는 아까 res.status(200).json({ name: 'doeunnkimm' })을 응답 했었습니다.

 

따라서 화면은 아래와 같이 될 겁니다.

실행 화면

정리해 보자면 다음과 같습니다.

 

- res.status(code)

- res.json(body)

- res.redirect(code, url)

- res.send(body)

 


이번 글에서는 API Routes에 대해 알아보았습니다 :)

 

1. API란?

API란 Application Programming Interface로, 프로그램 간의 연결 혹은 컴퓨터와 컴퓨터간의 연결입니다.

저희는 이번 글에서 프론트 서비스와 백엔드 서비스 간의 연결을 살펴보았고, 거기에서 정의된 api를 활용하는 방법에 대해 알아보았습니다.

 

2. API Routes

Next.js에서 API Routes를 제공합니다. 프론트엔드는 프론트 서비스만 만들지만 어떤 테스트를 하거나 실제 서비스를 배포할 때 서버의 api를 동일하게 이용해야 하는 경우가 있는데 이때 이용할 수 있겠습니다.

추가로, Next.js의 API Routes는 Routing과 동일했습니다. 파일 기반이였으며 Dynamic하게도 동일하게 가능했습니다. 또한 slug를 사용하여 옵셔널 하게도 가능해 여러 값들을 Dynamic하게 적용할 수도 있었습니다.

 

3. Middlewares

미들웨어들을 여러 개 추가할 수 있는데, 우리는 이번에 빌드인 되어 있는 것들을 살펴보았습니다. req.query, req.cookies 이런 것들만 살펴보았지만 이외에도 추가가 가능합니다.

 

4. Response

단순하게 status, json, redirect, send 등도 가능했습니다.

728x90
LIST
250x250
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/11   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
글 보관함