Skip to main content
  1. Guides 리스트/
  2. Next.js 답게 개발하기: 앱 라우터의 설계 원리와 실전 가이드/

Next.js 중복 API 요청 Request Memoization으로 완벽하게 막는 법

·377 words·2 mins·
Next.js 답게 개발하기: 앱 라우터의 설계 원리와 실전 가이드 - This article is part of a series.
Part 3: This Article

결론부터 말씀드리면, 데이터 페칭 로직을 별도의 레이어로 분리해서, ‘리퀘스트 메모이제이션’의 효과를 제대로 누릴 수 있는 설계를 하는 게 좋은데요.

이게 바로 이번 챕터의 핵심입니다.

왜 분리가 필요할까
#

지난 글에서 Next.js는 데이터 페칭 ‘코로케이션(colocation)‘을 권장한다고 말씀드렸거든요.

가장 말단의 컴포넌트에서 데이터를 가져오는 이 방식은 중복 요청의 위험이 따르지만, Next.js는 ‘리퀘스트 메모이제이션(Request Memoization)‘이라는 기능으로 이 문제를 해결합니다.

하지만 여기에 아주 중요한 조건이 하나 있는데요.

Next.js가 두 요청을 ‘동일’하다고 판단하려면, fetch 함수의 URL은 물론이고 함께 전달되는 옵션 객체까지 ‘완벽하게’ 일치해야만 합니다.

만약 옵션 중 단 하나라도 달라지면, 바로 별개의 새로운 리퀘스트로 인식해 버리거든요.

이게 바로 우리가 주의해야 할 포인트입니다.

가장 확실한 해결책 데이터 페칭 레이어 분리
#

실수로 옵션을 다르게 지정해서 메모이제이션이 작동하지 않는 상황을 막으려면, 여러 컴포넌트에서 사용할 데이터 페칭 로직은 별도의 ‘데이터 페칭 레이어’로 분리하는 것이 가장 좋은데요.

아래 코드처럼 함수로 만들어 중앙에서 관리하는 것입니다.

// 상품 정보를 가져오는 데이터 페칭 레이어
export async function getProduct(id: string) {
  const res = await fetch(`https://dummyjson.com/products/${id}`, {
    // 여기에 공통으로 사용할 헤더나 옵션을 지정합니다.
  });
  return res.json();
}

파일은 어디에 둘까
#

Next.js는 코로케이션을 굉장히 중요하게 생각하는 프레임워크거든요.

그래서 데이터 페칭 레이어를 파일로 분리할 때도, 사용하는 컴포넌트 근처에 두는 것이 좋습니다.

예를 들어, 아까 만든 getProduct() 함수를 분리한다면 저라면 아래와 같은 구조를 고려해 볼 텐데요.

상황에 맞게 선택하시면 됩니다.

app/products/fetcher.ts

products 폴더 아래에 파일이 많지 않고, 데이터 페칭 함수도 몇 개 없을 때 가장 단순한 구조입니다.

app/products/_lib/fetcher.ts

products 폴더 아래에 다른 파일들이 많을 때, _lib 같은 내부 라이브러리 폴더를 만들어 관리하는 구조입니다.

app/products/_lib/fetcher/product.ts

데이터 페칭 함수가 여러 개로 늘어날 경우, 기능별로 파일을 더 잘게 쪼개서 관리하는 구조입니다.

물론 파일명이나 디렉터리 구조는 개발 규모나 팀의 스타일에 따라 달라지니까요.

이건 팀원들과 함께 명확한 규칙을 정하는 것이 가장 좋습니다.

실수를 원천 차단하는 ‘server-only’
#

이전 글에서 데이터 페칭은 기본적으로 서버 컴포넌트에서 해야 한다고 강조했는데요.

실수로 이 데이터 페칭 함수들을 클라이언트 사이드에서 임포트하는 것을 막기 위해, ‘server-only’ 패키지로 모듈을 보호하는 것을 강력히 추천합니다.

// 이 파일을 클라이언트 컴포넌트에서 import하면 빌드 에러가 발생합니다.
import "server-only";

export async function getProduct(id: string) {
  const res = await fetch(`https://dummyjson.com/products/${id}`, {
    // ...
  });
  return res.json();
}

이렇게 파일 최상단에 import "server-only"; 한 줄만 추가하면, 이 모듈을 클라이언트 컴포넌트에서 임포트하려고 할 때 빌드 에러가 발생해서 실수를 원천 차단해 줍니다.

트레이드오프
#

이 방식의 트레이드오프는 특별히 없는데요.

오히려 데이터 페칭 로직이 중앙에서 관리되므로, 애플리케이션의 안정성과 유지보수성이 크게 향상되는 장점만 있을 뿐입니다.

Next.js 답게 개발하기: 앱 라우터의 설계 원리와 실전 가이드 - This article is part of a series.
Part 3: This Article