lottie
Seungjun's blog
blog
data fetching (server fetch)

nextjs13에서 데이터를 fetch하는 방법에는 다음과 같은 네 가지가 있다.


1. 서버에서fetch

2. 서버에서 서드파티 라이브러리 사용

3. 클라이언트에서 route handler를 통해

4. 클라이언트에서 서드파티 라이브러리를 사용


이번 글에서는 서버에서의 데이터 fetch에 대해 알아보자.

1. 서버에서 fetch

Next.js는 기본적으로 제공되는 fetch Web API를 확장하여 서버에서 각 fetch 요청에 대한 캐싱 및 revalidation 동작을 구성할 수 있도록 합니다. React는 fetch를 확장하여 React 컴포넌트 트리를 렌더링하는 동안 자동으로 fetch 요청을 메모이제이션할 수 있게 합니다.

 fetch를 async/await와 함께 Server Components, Route Handlers, 그리고 Server Actions에서 사용할 수 있습니다.


예시코드 :


async function getData() {
  const res = await fetch('https://api.example.com/...')
  // The return value is *not* serialized
  // You can return Date, Map, Set, etc.
  if (!res.ok) {
    // This will activate the closest `error.js` Error Boundary
    throw new Error('Failed to fetch data')
  }
  return res.json()
}
export default async function Page() {
  const data = await getData()
  return <main></main>
}

Caching Data

      기본적으로 Next.js는 서버의 Data Cache에 fetch의 반환 값을 자동으로 캐싱합니다. 이는 데이터가 빌드 중이나 request 시에 가져와서 캐시하고 각 데이터 request 마다 재사용될 수 있음을 의미한다.


  이 부분이 크게 달라졌다. pages 디렉토리를 사용하는 버전에서는 getStaticProps 와 getServerSideProps 등을 이용했는데, app 디렉토리를 이용하는 13버전 이후부터는 그럴 필요가 없어졌다.

 fetch 요청 중 POST 메서드를 사용하는 경우에도 자동으로 캐싱됩니다. 그러나 POST 메서드를 사용하는 Route Handler 내부에 있는 경우에는 캐싱되지 않습니다.


// 'force-cache' is the default, and can be omitted
fetch('https://...', { cache: 'force-cache' })


Revalidating Data ( ISR: Incremental Static Regeneration )

      revalidation은 데이터 캐시를 지우고 최신 데이터를 다시 가져오는 과정입니다. 이는 데이터가 변경되고 최신 정보를 보여주기 위해 사용됩니다. 캐시된 데이터는 두 가지 방법으로 revalidation할 수 있습니다.


  1. 시간 기반 재유효화: 일정 시간이 경과한 후에 자동으로 데이터를 revalidation합니다. 이는 변경 빈도가 낮고 신선도가 크게 중요하지 않은 데이터에 유용합니다. 일정 시간 간격마다 데이터를 revalidation하려면 fetch의 next.revalidate 옵션을 사용하여 리소스의 캐시 지속 시간(초 단위)을 설정할 수 있습니다.

    (예시 코드: fetch('https://...', { next: { revalidate: 3600 } }))

  • 추가로 정적으로 렌더링된 route에서 여러 개의 fetch 요청이 있고 각각 다른 재유효화 주기를 가지는 경우, 모든 요청에 대해 가장 짧은 시간이 재유효화 주기로 사용됩니다. 즉, 모든 fetch 요청은 가장 짧은 시간 간격을 기준으로 재유효화됩니다.

    반면, 동적으로 렌더링된 route에서는 각각의 fetch 요청이 독립적으로 재유효화되며 개별 요청에 지정된 재유효화 주기에 따라 수행됩니다. 이는 동적으로 렌더링된 경로 내에서 각각의 fetch 요청에 대한 재유효화 동작을 보다 유연하게 제어할 수 있도록 합니다.

  1. 요청 기반 재유효화: 이벤트(예: 폼 제출)에 기반하여 수동으로 데이터를 revalidation합니다. 요청 기반 재유효화는 태그(tag) 또는 경로(path) 기반 접근 방식을 사용하여 한 번에 여러 개의 데이터 그룹을 revalidation할 수 있습니다. 이는 가능한 빠르게 최신 데이터가 표시되도록 하려는 경우 유용합니다 (예: 헤드리스 CMS에서 콘텐츠가 업데이트된 경우).


On-demand Revalidation

     데이터는 Route Handler 또는 Server Action 내부에서 경로(revalidatePath) 또는 캐시 태그(revalidateTag)를 통해revalidation될 수 있습니다.

     Next.js에는 라우트 간에 fetch 요청을 무효화하기 위한 캐시 태깅 시스템이 있습니다.

  1. fetch를 사용할 때 하나 이상의 태그로 캐시 항목을 태그 지정할 수 있습니다.

  2. 그런 다음 revalidateTag를 호출하여 해당 태그와 연관된 모든 항목을 재유효화할 수 있습니다.

 예를 들어, 다음과 같은 fetch 요청은 "collection"이라는 캐시 태그를 추가합니다.


export default async function Page() {
  const res = await fetch('https://...', { next: { tags: ['collection'] } })
  const data = await res.json()
  // ...
}



Opting out of Data Caching

fetch 요청이 캐시되지 않는 경우

  • fetch 요청에 cache: 'no-store' 옵션이 추가된 경우

  • 개별 fetch 요청에 revalidate: 0 옵션이 추가된 경우

  • POST 메서드를 사용하는 Router Handler 내부에 fetch 요청이 있는 경우

  • fetch 요청이 헤더나 쿠키 사용 이후에 오는 경우

  • const dynamic = 'force-dynamic' route segment 옵션이 사용된 경우

  • fetchCache route segment 옵션이 기본적으로 캐시를 건너뛰도록 구성된 경우

  • fetch 요청이 Authorization 또는 Cookie 헤더를 사용하고 컴포넌트 트리에서 위쪽에 캐시되지 않은 요청이 있는 경우