Next.js 로 만든 API를 클라이언트에서 바로 사용하기 - 배포까지 적용

chris0205.eth·2023년 8월 28일
0

Next.js

목록 보기
1/1
post-thumbnail

본 글에서 사용된 Next.js는 app router를 적용하였습니다.

Next.js로 Rest API 만들기

/app/api/vault 와 같이 폴더를 만들어주면, site_url/api/vault 로 api 요청을 보낼 수 있습니다.

이때, vault의 폴더 내부에는 route.js라는 이름의 파일을 만들어주어야 합니다.

미리 dummy.json이라는 이름의 더미 데이터 파일을 만들어 둡니다.

[
  {
    "id": 1,
    "name": "WETH/USDT",
    "chain": "arbitrum",
    "v_address": "0x82aF49447D8a07e3bd95BD0d56f35241523fBab1"
  },
  {
    "id": 2,
    "name": "WETH/ARB",
    "chain": "arbitrum",
    "v_address": "0x82aF49447D8a07e3bd95BD0d56f35241523f1234"
  },
  {
    "id": 3,
    "name": "USDC/USDT",
    "chain": "optimism",
    "v_address": "0x123449447D8a07e3bd95BD0d56f35241523f5678"
  },
  {
    "id": 4,
    "name": "WETH/USDC",
    "chain": "optimism",
    "v_address": "0x38B26d26e575b70AE37f7390A22711500773A00E"
  },
  {
    "id": 5,
    "name": "WETH/DAI",
    "chain": "arbitrum",
    "v_address": "0xbc73933C8CA2b32ef3fB6B6aC8a53070EB05F9fd"
  }
]

그리고, route.js 파일에 다음과 같은 코드를 작성해줍니다.

import { NextResponse } from "next/server";

import vault from "@/dummy.json";

export async function GET(request) {
  const { searchParams } = new URL(request.url);
  const name = searchParams.get("name");

  const lowerCaseName = name?.toLowerCase();
  const vaultData = vault.filter((item) => {
    const lowerCaseItemName = item.name.toLowerCase();
    return lowerCaseItemName.includes(name ?? "");
  });
  return NextResponse.json({ vaultData });
}

위 코드를 간단하게 살펴보면, 해당 url에 GET 요청으로 name 파라미터를 받을 경우에 해당 name을 가진 vaultData 를 반환해주고 있습니다.

이렇게 매우 간단하게 api 하나를 만들었습니다!

RTK query 사용하여 vaultData 불러오기

그럼 이제 이렇게 만든 API를 클라이언트 측에서 사용해보겠습니다.

본 글에서는 data fetching, loading handling 등을 한번에 가능하게 해주는 RTK query로 api를 사용할 예정입니다.

RTK query SETUP

RTK query는 리덕스와 함께 사용할 수도 있고, 따로 사용할 수도 있는 본 글에서는 함께 사용하는 것을 기준으로 구현해보겠습니다.

import { createApi, fetchBaseQuery } from "@reduxjs/toolkit/query/react";

export const vaultApi = createApi({
  reducerPath: "vaultApi",
  tagTypes: ["vault"],
  baseQuery: fetchBaseQuery({
    baseUrl: `${process.env.NEXT_PUBLIC_SITE_URL}/api`, // NEXT_PUBLIC_SITE_URL 관련해서는 아래에서 설명 예정
  }),
  endpoints: (builder) => ({
    search: builder.query({
      query: (q) => `vault?name=${q}`,
      providesTags: (result, error, arg) => [{ type: "vault", search: arg }],
    }),
  }),
});

리덕스 툴킷의 createApi를 이용해서 위와 같이 어떤 url로 어떤 요청을 보낼지 정의해둡니다.

다음으로 reducer를 정의해서 사용할때와 마찬가지로 리덕스의 store 설정해줘야 합니다.

import { configureStore } from "@reduxjs/toolkit";

import { vaultApi } from "./vaultApi";

const store = configureStore({
  reducer: {
    [vaultApi.reducerPath]: vaultApi.reducer,
  },
  middleware: (getDefaultMiddleware) =>
    getDefaultMiddleware().concat(vaultApi.middleware),
});

export default store;

Using RTK query

이렇게 만든 vaultApi를 use ~ Query 형태의 훅으로 사용할 수 있습니다.

import { vaultApi } from "@/stores/vaultApi";

export default function VaultList() {
	const { data, error, isFetching } = vaultApi.useSearchQuery(search);

	return (
    <>
      <ul>
        {isFetching ? (
          <Stack spacing={2}>
            <Skeleton variant="rounded" width={1020} height={118} />
            <Skeleton variant="rounded" width={1020} height={118} />
            <Skeleton variant="rounded" width={1020} height={118} />
            <Skeleton variant="rounded" width={1020} height={118} />
            <Skeleton variant="rounded" width={1020} height={118} />
          </Stack>
        ) : (
          data?.vaultData.map((vault) => {
            return (
              <li key={vault.v_address} className={classes.vaultListContainer}>
                { /* ... 중략 ... */ }
              </li>
            );
          })
        )}
      </ul>
    </>
  );

이렇게 손쉽게 검색 기능이 적용된 data fetching, caching, error handling, loading handling 기능을 완료했습니다!

Vercel 및 Next.js 환경 변수 설정하기

Next.js의 환경변수 설정

앞서 stores/vautlApi.js 에서 NEXT_PUBLIC_SITE_URL 이 나왔습니다. Next.js에서는 크게 3가지 방식으로 환경변수 기능을 지원합니다.

  1. process.env.NODE_ENV
  2. .env file
  3. NEXTPUBLIC

먼저 1번은 구동 환경이 development, production, test인지에 따라 각기 다른 값을 가지는 환경변수입니다. 이는 서버와 브라우저(서버 컴포넌트 & 클라이언트 컴포넌트)에서 모두 참조할 수 있는 환경변수입니다. development는 next dev로 구동하면 세팅되는 개발환경이고, production은 next build 후, next start로 구동할 때 세팅됩니다. 마지막으로 test는 테스트 환경에서 세팅될 수 있습니다.

두번째로 .env 파일을 설정해두면, 구동 환경에 맞는 파일이 자동으로 적용됩니다.

1) .env 파일 : 모든 환경에서 공통적으로 적용할 디폴트 환경변수를 정의한다. 가장 우선순위가 낮다.

2) .env.development 파일: 개발 환경(process.env.NODE_ENV === 'development') 에서 적용된다.

3) .env.production 파일: 배포/빌드 환경(process.env.NODE_ENV === 'production') 에서 적용된다.

4) .env.test 파일: 테스트 환경(process.env.NODE_ENV === 'test') 에서 적용된다.

5) .env.local 파일 : 가장 우선순위가 높다. 다른 파일들에 정의된 값들을 모두 덮어쓴다.(오버라이드)

마지막으로 NEXTPUBLIC은 브라우저 참조용 prefix입니다. 해당 prefix가 적용된 채로 환경변수를 세팅하면 서버와 브라우저 모두에서 환경변수에 접근이 가능합니다.

Vercel 환경 변수 및 브랜치 설정

vercel은 next.js를 이용해서 웹 호스팅하기 매우 간단한 서비스입니다. 프로젝트의 main branch는 자동으로 production 모드로 감지된 후 배포됩니다. 추가적으로 특정 브랜치를 preview 모드로 배포할 수도 있는데, 저는 dev 브랜치를 preview 모드로 배포하는 설정을 해뒀습니다.

다음으로 환경변수를 사용하여 배포하기 위해선 프로젝트 셋팅에서 아래와 같이 각 배포 환경 별로 환경변수를 설정해주면 됩니다.

이제 main 브랜치 혹은 dev 브랜치로 병합을 할때마다 자동으로 배포가 진행됨을 확인할 수 있습니다!

profile
long life, long goal

0개의 댓글