"use client";
import { useEffect, useState } from "react";
export default function HomePage() {
const [isLoading, setIsLoading] = useState(true);
const [movies, setMovies] = useState([]);
const getMovies = async () => {
const response = await fetch(`${process.env.NEXT_PUBLIC_BASE_URL}/movies`);
const json = await response.json();
setMovies(json);
setIsLoading(false);
};
useEffect(() => {
getMovies();
}, []);
return <div>{isLoading ? "Loading..." : JSON.stringify(movies)}</div>;
}
평소에 우리가 react.js를 사용해서 api와 통신하는 방식은 위와 같다.
그런데, client 쪽에서 통신을 하게 되면 개발자도구 api 키에 누구나 접근 가능해진다.
보안에 굉장히 취약해 진다... 💣
SSR을 하는 Next.js에서는 어떤식으로 fetch를 할 수 있을까?
export const metadata = {
title: "HOME",
};
async function getMovies() {
// 로딩 상태를 위해 일부러 프로그램을 느리게 만들어주는 트릭 (실제로는 필요 없는 코드임!!)
// getMovies 함수가 이 구문에서 2초간 멈췄다가 실행될 것이다.
// 그럼 사용자는 화면이 로딩될 때 까지 접근이 불가능하다.
await new Promise((resolve) => setTimeout(resolve, 500));
// 하지만!! loading.tsx라는 파일을 page.tsx와 동일한 경로에 만들어주면
// next가 알아서 자동으로 해당 컴포넌트를 화면에 로딩이 완료될때 까지 띄워준다.
// 라이브러리 필요 없이 자동으로 url을 fetch해 준다.
// 첫 fetch때만 API에 요청을 한다.
// 그리고 그 결과 상태를 기억해 두었다가 다음 부터는 재사용한다. 그래서 빨라보임
const response = await fetch(`${process.env.NEXT_PUBLIC_BASE_URL}/movies`);
const json = await response.json();
return json;
}
export default async function HomePage() {
const movies = await getMovies();
return <div>{JSON.stringify(movies)}</div>;
}
훨씬 간결해 졌다.
그리고 서버에서 이미 모든 작업을 완료하고 그 값들만 return해 주기 때문에 안전하게 API를 보호할 수 있다.
개발자 도구 network 탭에서 확인해 보니,
API 노출 없이 데이터만 쏙 빼내서 가져온 것을 확인해 볼 수 있다.
next.js 14 버전입니다