--- title: Стратегии получения данных description: Как выбрать получение REST-данных с учётом рендера страницы. keywords: [rest, стратегии, render, isr, ssr, server components, swr, promise, business] --- # Стратегии получения данных Как выбрать получение REST-данных с учётом рендера страницы. Перед выбором стратегии должен быть создан REST-клиент сервиса. Если клиента ещё нет, начните с раздела [Создание клиента](../clients/index.md). ## Сначала определите рендер страницы В Next.js выбор начинается не с `await`, `Suspense` или SWR. Сначала нужно понять, какой рендер получится у маршрута: static/ISR или dynamic/SSR. Next.js может перевести страницу в dynamic rendering автоматически, если в маршруте используются API текущего запроса. Поэтому первый вопрос такой: ```text Можно ли сохранить ISR, или странице нужны данные на каждый request? ``` ISR — приоритет. Если данные общие для пользователей и их можно обновлять с интервалом, не переводите страницу в SSR без необходимости. SSR/dynamic rendering выбирается только когда данные действительно зависят от текущего request или должны пересчитываться на каждый запрос. ## Что переводит страницу в dynamic rendering Проверьте, нужны ли странице API и настройки, которые делают маршрут динамическим: - `cookies()` — данные зависят от cookie текущего пользователя. - `headers()` — данные зависят от request headers. - `draftMode()` — нужен preview/draft-режим. - `searchParams` в `page.tsx` — данные зависят от query string. - `cache: 'no-store'` или `revalidate: 0` в методе клиента — запрос нельзя кешировать. - `connection()` — рендер явно ждёт request. - `export const dynamic = 'force-dynamic'` — SSR включён вручную. Если ничего из этого не нужно, сначала проектируйте страницу как static/ISR. Серверный `await` сам по себе не означает SSR: режим зависит от кеширования запроса и dynamic API маршрута. ## Рендер перед стратегией | Рендер | Когда подходит | Что выбирать дальше | |--------|----------------|---------------------| | Static/ISR | Данные общие и могут обновляться по интервалу | Серверные стратегии: `await`, `Promise.all`, передача промиса ниже, SWR `fallback` | | SSR/dynamic | Данные зависят от request, пользователя или должны быть свежими на каждый запрос | Серверные стратегии с учётом блокировки первого HTML | | После гидрации | Данные зависят от вкладки, фильтра, поиска, пагинации или действия пользователя | Клиентский GET-хук | ## Как выбрать стратегию Когда режим рендера понятен, выбирайте конкретный способ получения данных: | Ситуация после выбора рендера | Стратегия | Где читать | |-------------------------------|-----------|------------| | Данные обязательны для первого HTML, SEO, `notFound()` или `redirect()` | Серверный `await` | [Серверный await](./server-await.md) | | Несколько независимых данных нужны до рендера | Запуск промисов + `Promise.all` | [Параллельные серверные запросы](./parallel-server-requests.md) | | Часть UI можно загрузить отдельно | Передача промиса ниже + `Suspense` | [Передача промиса ниже](./pass-promise-down.md) | | Client Component должен получить данные сразу из SWR | Начальные данные для клиентских хуков | [Начальные данные для клиентских хуков](./client-hooks-initial-data.md) | | Данные зависят от client state | Клиентский GET-хук | [Клиентский GET-хук](./client-get-hook.md) | | Нужно объединить несколько запросов или вычислить `isAuth`, `canEdit`, `hasPets` | Business-композиция | [Business-композиция](./business-composition.md) | ## Правило выбора Не выбирайте стратегию по любимому инструменту. Выбирайте её по двум вопросам: ```text Можно ли сохранить ISR? Где нужны данные и что должно произойти до первого HTML? ``` Если данные можно кешировать между пользователями — сохраняйте static/ISR. Если данные request-specific — используйте SSR/dynamic rendering. Если данные зависят от состояния браузера — используйте GET-хук REST-клиента. Если простой GET превращается в доменный сценарий — переходите в `business/`. ## Общие запреты ```tsx // Плохо — SSR включён на всякий случай export const dynamic = 'force-dynamic' // Плохо — ISR отключён без требования к свежести на каждый request export const revalidate = 0 // Плохо — прямой fetch в компоненте useEffect(() => { fetch('/api/pets').then(...) }, []) // Плохо — useSWR в компоненте const { data } = useSWR( ['pet-store-api', 'pet', 'list', status], () => petStoreApi.pet.findPetsByStatus({ status }), ) // Плохо — бизнес-флаг внутри GET-хука REST-клиента return { ...query, hasPets: Boolean(query.data?.length), } ``` Не отключайте ISR без причины. В компонентах используются готовые методы клиента или готовые хуки. SWR-ключи, fetcher и транспорт остаются внутри REST-модуля.