원티드 프리온 보딩 챌린지

yesolog·2023년 11월 27일
0

개발일지

목록 보기
2/6
post-thumbnail

12월 사전과제

실전스킬: 비즈니스 로직 완전 정복 with React

힘들었던 로직으로는 최근에 진행한 프로젝트인 mpviedog의 년도별 카테고리 목록이다.

NextJS, TypeScript를 배우고 바로 시도한 첫번째 프로젝트인데 처음 배우는 두개의 내용을 접목하려니 정말 우당탕탕…

일단 NextJS를 프로젝트에서 사용하기로 하면서 꼭 해보고 싶었던 건 2가지다.
1. SSR
2. rewrites로 api키 숨기기

이 두가지를 메인으로 잡고 가는데 여기에 TypeScript가 합쳐지니 좀 힘들었다.

먼저 년도별 카테고리를 헤더에서 클릭하면 해당 페이지로 이동하면서 year와 idx값이 url에 설정된다. 그러면 getServerSideProps에서 해당 값을 context.params를 사용하여 가져와서 url과 합성하여 rewrites로 보낸다.

// 년도별 카테고리 페이지
export const getServerSideProps = async (
  context: GetServerSidePropsContext,
) => {
  const params = context.params as ParsedUrlQuery;
  let year = '2020';
  let idx = '1';
  //next.config.js로 생성한 url
  const response = await fetch(
    `http://localhost:3000/api/movie/${year}/${idx}`,
  );
  const { results } = await response.json();
  return {
    props: {
      data: results,
      year: year,
      idx: idx,
    },
  };
};

rewrites에서 다시 그 값으로 올바르게 TMDB로 api를 패치하여 데이터를 가져오는 이러한 로직인데… context부터 이 year와 idx를 서버단에서 설정하는게 매우 곤혹스러웠다.

사실 이 부분은 chatGpt의 도움을 받았다… 보통은 어떻게든 손으로 써가며 로직을 만들어내는데 당장 급해서… 도움을 받는것도 나쁘지는 않았다.

그리하여 완성된 코드

export const getServerSideProps = async (
  context: GetServerSidePropsContext,
) => {
  const params = context.params as ParsedUrlQuery;

  //params가 undefined인지 확인하고, 해당 경우 기본값인 year와 idx를 설정
  let year = '2020';
  let idx = '1';

  if (params && params.parmas) {
    // params.parmas가 존재하고 배열인지 여부를 확인하고, 값에 접근하여 year와 idx 변수를 설정
    const paramArray = Array.isArray(params.parmas)
      ? params.parmas
      : [params.parmas];
    year = paramArray[0] as string;
    idx = paramArray[1] ? (paramArray[1] as string) : '1';
  }

  const response = await fetch(
    `http://localhost:3000/api/movie/${year}/${idx}`,
  );
  const { results } = await response.json();

  return {
    props: {
      data: results,
      year: year,
      idx: idx,
    },
  };
};

rewrites를 작성한 next.config.js 코드

//next.config.js
/** @type {import('next').NextConfig} */
const API_KEY = process.env.NEXT_PUBLIC_TMDB_API_KEY_AUTH;
const nextConfig = {
  reactStrictMode: true,
  images: {
    remotePatterns: [
      {
        protocol: 'http',
        hostname: 'image.tmdb.org',
      },
    ],
  },
  webpack(config) {
    config.module.rules.push({
      test: /\.svg$/,
      use: ['@svgr/webpack'],
    });
    return config;
  },
  // 위의 년도별 카테고리 페이지에서 패치한 URL
  // 여기로 들어오면 destination으로 경로를 바꿈
  async rewrites() {
    return [
      {
        source: '/api/movie/:year/:idx',
        destination: `https://api.themoviedb.org/3/discover/movie?include_adult=false&include_video=false&language=ko-KR&page=:idx&primary_release_date.gte=:year-01-01&primary_release_date.lte=:year-12-31&api_key=${API_KEY}&sort_by=vote_count.desc`,
      },
    ];
  },
};

module.exports = nextConfig;

이런 과정을 거쳐서 rewrites로 접근한 이후에는 year와 idx값을 받아야 했고 이건 동적경로매개변수를 사용해서 사용할 수 있었다. 이후에는 순탄하게 잘 넘어갔다. 그래서 배포를 했는데 년도별 페이지만 가면 504페이지와 함께 server time out 에러가 발생한 것… 지인과 함께하는 플젝이라 버셀을 pro 버전으로 구매하지 않아서 배포한 팀원이 캡쳐를 보여주고나서야 깨달았다… 정말이지 말도 안되는 실수를 한 것…

밑에 작성한 코드가 바로 에러가 발생한 원인이다.

// 년도별 카테고리 페이지의 getServerSideProps 함수 내부에 작성된 response

  const response = await fetch(
    `http://localhost:3000/api/movie/${year}/${idx}`,
  );

백엔드가 없이 진행되는 서버리스 프로젝트이다보니 우리는 TMDB의 데이터를 받아와서 사용했다.

특히 아까 메인으로 얘기했던 api키를 네트워크에서도 숨기고 싶어서 rewrites를 사용했다.

근데 rewirtes를 사용하면서 서버단에서 rewrites로 보내는 코드를 localhost:3000으로 설정하고 바꾸지 않은 상태에서 배포를 한 것…

그러니까 패치가 안된다고 vercel 에서 계속해서 에러를 보여줬던 것이다.

이번에 NextJS를 사용하면서 rewrites기능을 처음 사용해보면서 이런 초보적인 실수를 했다. 스택오버플로우에 해당 에러에 대한 질문글이 있어서 이러한 관련 문제가 은근… 발생할 법하다는 걸 깨달았다. 취준할 때 이러한 실수를 할 수 있다는 점을 알아서 천만 다행이다. 전에 서버팀과 함께 작업할 때는 미리 설정한 URI가 있으니 그걸로 쭉 가던 버릇으로 인해 발생한 문제… 어이없지만 꽤나 큰 시련으로 다가왔던 트러블 슈팅이다...

0개의 댓글