본문 바로가기

Frontend/Next

[NextJS] NextJS 시작하기 - 5. 영화 데이터 가져오기 & API KEY 숨기기 (feat. optional chanining, redirects, rewrites)

반응형

1. 영화 데이터 가져오기 (javascript & react 관련)

데이터 가져오기

  • https://www.themoviedb.org/?language=ko에서 영화 API를 사용한다.
  • 위 아래 코드의 결과는 동일하다. (아직 위 코드처럼 쓰는 게 익숙지 않다..)
useEffect(() => {
    (async () => {
      const { results } = await (
        await fetch(
          `https://api.themoviedb.org/3/movie/popular?api_key=${API_KEY}`
        )
      ).json();
      setMovies(results);
    })();
  }, []);
useEffect(() => {
    const getMovie = async () => {
      const { results } = await (
        await fetch(
          `https://api.themoviedb.org/3/movie/popular?api_key=${API_KEY}`
        )
      ).json();
      setMovies(results);
    };
    getMovie();
  }, []);

 

화면에 뿌리기

API로 받아온 배열 데이터를 화면에 뿌리기 위한 순서는 다음과 같다.

  1. 배열 데이터를 저장할 변수 생성 후 초기화하기
  2. API로 데이터 받으면 미리 만들어 둔 변수에 저장하기
  3. 화면에 뿌리기 (return)

여기서 포인트는 useState([])를 통해 빈 배열로 초기화를 해주었다는 것이다. 그냥 useState()만 하게되면 map에서 에러가 발생하기 때문이다. (API를 통해 데이터를 받아오는 속도가 너무 느리면 movies에 값이 담기기 전에 map이 실행되면 에러 발생) 

const [movies, setMovies] = useState([]);

{movies.map((movie) => (
  <div key={movie.id}>
    <h4>{movie.original_title}</h4>
  </div>
))}

 

그럼 초기 변수를 초기화하지 않고 사용하는 방법은 없나?

optional chaining 연산자를 사용하면 된다. 이는 참조나 기능이 undefined 또는 null일 수 있을 때 연결된 객체의 값에 접근하는 단순화할 수 있는 방법을 제공한다. 두 가지 방법을 살펴보자.

  1. && 사용
  2. ?. 사용

두 가지 모두 결과는 동일하다. 차이가 있다면 ?. 연산자가 더 최신이라는 것?

const [movies, setMovies] = useState();

//1번
{movies && movies.map((movie) => (
  <div key={movie.id}>
    <h4>{movie.original_title}</h4>
  </div>
))}

//2번
{movies?.map((movie) => (
  <div key={movie.id}>
    <h4>{movie.original_title}</h4>
  </div>
))}

 

 

2. redirects과 rewrites를 통한 API_KEY 숨기기

Next에는 next.config.js 파일이 있다. 이를 통해 많은 기능을 사용할 수 있는데, 우선 redirectsrewrites에 대해 알아보자.

cf) next.config.js 파일을 수정 후 적용시키기 위해서는 서버를 재시작해야 한다.

 

1) redirects

  • source: 유저가 여기로 이동한 경우
  • destination: 여기로 보내기 (유저의 브라우저 창의 url 자체가 바뀜)
  • permanent: 브라우저나 검색엔진이 이 정보를 계속 기억할지 여부

 

ex1) /contact -> /form

module.exports = {
  reactStrictMode: true,
  async redirects() {
    return [
      {
        source: '/contact',
        destination: '/form',
        permanent: false,
      },
    ];
  },
};

 

ex2) /old-blog/123 -> /new/blog/123

source: '/old-blog/:path',
destination: '/new-blog/:path',

 

 

주소 뒤에 *를 붙이면 모든 것을 catch할 수 있다.

ex3) /old-blog/123/comments/8 -> /new/blog/123/comments/8

source: '/old-blog/:path*',
destination: '/new-blog/:path*',

 

2) rewrites

  • source: 유저가 여기로 이동한 경우
  • destination: 여기로 보내기 (내부적 이동: 유저의 브라우저 창에 보이지 않음)

redirects와 달리, 유저가 url의 변화를 볼 수 없다. 유저가 보는 url은 여전히 source이다.

이러한 특징을 이용해 API KEY를 숨길 수 있다.

 

HOW?

  • source: 데이터 fetch할 때 사용할 주소(임의 주소)로 설정
  • destination: API를 fetch할 때 사용했던 실제주소로 설정
  • 데이터 fetch하는 곳에서 source를 통해 fetch 가능

 

next.config.js

const API_KEY = process.env.API_KEY;

module.exports = {
  reactStrictMode: true,
  async rewrites() {
    return [
      {
        source: '/api/movies',
        destination: `https://api.themoviedb.org/3/movie/popular?api_key=${API_KEY}`,
      },
    ];
  },
};

 

pages/index.js

  useEffect(() => {
    (async () => {
      const { results } = await (await fetch(`api/movies`)).json();
      setMovies(results);
    })();
  }, []);

 

 

Reference

반응형