Next.js의 동적 라우팅 방법의 비교

Next.js에서 동적 라우팅을 해봤던 내용을 작성해보았다.

이커머스 사이트 등에서는 상품의 상세 페이지를 product/[id]와 같은 식으로 두곤 한. 이처럼 product의 id별로 페이지를 만들 때 Next.js에서는 동적 라우팅을 사용한.

문서 에 따르면 pages/product/[id].js 와 같은 파일을 생성해야 한다. 다 동적 라우팅을 위해서는 getStaticProps를 사용하는 방법과 getServerSideProps를 사용하는 방법이 있다.

getStaticProps와 getServerSideProps

getStaticProps는 빌드 시에 데이터를 호출하고, 호출된 값은 고정된다. 반면에 getServerSideProps는 요청 시마다 서버로부터 데이터를 호출하는 것을 말한다.

getStaticProps를 사용하는 방법

getStaticProps에서 데이터를 불러오려면 getStaticPaths를 함께 사용해야 한다. 다음의 코드처럼 getStaticPaths에서 가능한 경로들을 호출해서 리턴한다.

그리고 getStaticProps에서는 params의 id 값으로 각 상품의 데이터를 호출한다.

getStaticPaths에서 가능한 모든 경로를 주면 getStaticProps에서 빌드 시에 데이터를 호출하게 된다.

export const getStaticPaths = async () => {
	const allProducts = await getProducts()

	return {
		paths: allProducts,
		fallback: false
	}
}

export const getStaticProps = async ({ params }) -> {
	const productDetail = await getProductDetail(params.id);
	return {
		props: {
			productDetail
		}
	}
}

getStaticProps를 사용해서 동적 라우팅을 하게 되면, 빌드 시간이 더 오래 걸린다는 단점이 있지만, 페이지를 로드하는 시간은 짧아진다는 장점이 있다.

getServerSideProps를 사용하는 방법

getServerSideProps를 사용하게 되면 위의 코드를 아래 코드로 대체할 수 있는데, getStaticPaths도 필요없게 된다.

export const getgetServerSideProps = async ({ query: { id } }) => {
	const productDetail = await getProductDetail(id);
	return {
		props: {
			productDetail
		}
	}
}

위 코드에서는 query의 id 값으로 필요할 때마다 서버에서 데이터를 호출하게 된다.

getServerSideProps를 사용하면, getStaticProps를 사용했을 때와 반대로 빌드 시간은 줄어들고, 페이지를 로드하는 시간은 더 걸릴 수가 있다.

getServerSideProps를 사용해야 하는 이유

처음에는 문서를 보고 getStaticProps를 사용했었는데, 이렇게 하니 두 가지 문제가 있었다.

  1. product/[id] 페이지에 필요한 데이터가 손실되었을 경우 빌드 시에 에러가 난다.
  2. 어드민에서 상품을 등록하더라도 빌드해주지 않으면 등록한 상품이 반영되지 않는다.

    (상품을 등록할 때마다 배포해줘야 한다.)

getServerSideProps를 사용하면 1번과 같은 경우에도 빌드는 가능하지만, 해당 페이지는 흰 화면으로 나타난다. 1번은 getServerSideProps를 사용한다고 해서 해결되는 문제는 아니지만, 덜 심각해 보인다. (물론 따로 처리는 해줘야 한다.)

2번의 이유로 서버사이드에서 데이터를 호출하는 방식을 사용해야 하는데, 상품 등록 시마다 빌드를 해줘야 한다면 어드민을 둠으로써 얻을 수 있는 편리함이 줄어들 게 된다. 그러므로 데이터의 추가/수정 작업이 있을 경우에는 getServerSideProps를 사용해야 하지만, 데이터가 추가될 일이 거의 없다거나 한다면 getStaticProps를 사용해서 동적 라우팅을 하는 것도 좋을 것 같다.


Written by@jaeeun
I explain with words and code. I explain with words and code. I explain with words and code.