Руководство по выбору · Next.js

Next.js фоновые задачи: когда after(), Server Actions и Route Handlers не хватает

App Router Next.js даёт <code>after()</code>, Server Actions и Route Handlers для работы после ответа. У каждого примитива свой профиль — и своя точка отказа, после которой нужен внешний worker-уровень. Эта страница — руководство по выбору: читайте таблицу, выбирайте нужный примитив и смотрите, как передать работу в пайплайн Inquir, когда нужно пережить HTTP-окно.

Обновлено: 2026-06-23

  • Используйте after(): быстрые побочные эффекты после ответа внутри таймаута платформы.
  • Используйте Server Actions: мутации из форм; передавайте в Inquir, когда побочный эффект медленный или должен повторяться независимо.
  • Используйте Route Handler + Inquir: явный 202 ACK, задача в очереди Inquir, пользователь не ждёт медленной работы.
  • Используйте полный пайплайн Inquir: многошаговая оркестрация, cron, параллельный fan-out, продолжение вебхуков.

Суть ответа

Next.js фоновые задачи: когда after(), Server Actions и Route Handlers не хватает. Server Action или Route Handler вызывает шлюз Inquir с API-ключом и возвращает клиенту 202 немедленно. Пайплайны Inquir — очередь, повторы, секреты и история; те же функции, что для cron и вебхуков.

Когда подходит и когда нет

  • Побочный эффект в Server Action или Route Handler может упасть независимо, нужны повторы или он выходит за таймаут платформы.
  • Нужны cron-задачи, продолжение вебхуков или параллельный fan-out с видимой историей рядом с кодом App Router.

На что обратить внимание

  • after() и Fluid Compute — правильный выбор для IO-задач внутри таймаута: логирование, аналитика, прогрев кэша, один вызов внешнего API.
  • Vercel Cron в vercel.json подходит для лёгких расписаний на секунды. Как только нужна многошаговая оркестрация, ретраи на уровне шага, видимая история или работа, которая реально переживает вызов функции — нужен отдельный job-уровень.

Почему фоновые примитивы Next.js упираются в лимиты

after() и Server Actions откладывают работу после ответа — но на Vercel всё ещё в рамках одного вызова функции с таймаутом платформы. PDF, массовая рассылка, медленные цепочки API и большие файловые трансформации — типичные «жертвы». Примитивы не сломаны; работа просто не должна жить в обработчике запроса.

Команды тянут BullMQ, Inngest или отдельный worker-контейнер — ещё один деплой, хранилище секретов и дашборд, когда вебхук Stripe или ночная синхронизация падают в 3 ночи.

Когда хватает встроенных инструментов Next.js

after() и Fluid Compute — правильный выбор для IO-задач внутри таймаута: логирование, аналитика, прогрев кэша, один вызов внешнего API.

Vercel Cron в vercel.json подходит для лёгких расписаний на секунды. Как только нужна многошаговая оркестрация, ретраи на уровне шага, видимая история или работа, которая реально переживает вызов функции — нужен отдельный job-уровень.

Next.js остаётся тонким; Inquir — медленный путь

Server Action или Route Handler вызывает шлюз Inquir с API-ключом и возвращает клиенту 202 немедленно. Пайплайны Inquir — очередь, повторы, секреты и история; те же функции, что для cron и вебхуков.

Одно рабочее пространство для HTTP, расписаний и async jobs — без Redis, без Dockerfile worker рядом с репозиторием Next.js, только URL шлюза, который приложение уже умеет вызывать через fetch.

Таблица выбора фонового примитива Next.js

Найдите строку, соответствующую вашей задаче. У каждого примитива есть точка отказа — зная её, легче решить, когда передавать работу в пайплайн Inquir.

Таблица выбора фонового примитива Next.js
ПримитивДля чегоТочка отказаКогда нужен Inquir
after()Быстрые побочные эффекты после ответа (аналитика, сброс кэша, один API-вызов)Работает внутри вызова функции; завершается по таймауту вместе с запросом на VercelРабота может упасть независимо, нужны повторы или она выходит за таймаут платформы
Server ActionМутации из форм: создание, обновление, валидация — с оптимистичным UIДолгий побочный эффект блокирует action; таймаут молча обрывает работуПобочный эффект (email, PDF, sync) медленный или должен повторяться независимо от формы
Route Handler (синхронный)REST API: auth, CRUD, быстрый ACK вебхукаНе может пережить таймаут функции; медленная работа блокирует ответ клиентуКлиент ожидает 202 и работа должна выполняться асинхронно с повторами и историей
Route Handler + шлюз InquirAsync handoff: валидация, enqueue в Inquir, 202 сразуДобавляет сетевой hop; шлюз Inquir — внешняя зависимостьРабота медленная, нужны ретраи на шаг или она должна выполняться отдельно по cron
Полный пайплайн InquirМногошаговая оркестрация, cron, продолжение вебхуков, параллельный fan-outТребует внешнего сервиса; больше операционных затрат, чем after() для простых эффектовНужен, когда у работы несколько шагов, нужны ретраи на каждом или расписание

Next.js App Router + Inquir: паттерны интеграции

Handoff из Server Action

Server Action валидирует форму и ставит задачу в Inquir; action завершается немедленно. Шаг пайплайна выполняет медленный эффект — отправку email, сборку PDF, синхронизацию данных — вне таймаута action.

Route Handler 202 ACK

App Router POST валидирует ввод, вызывает шлюз Inquir и возвращает 202 до старта пайплайна. Клиент опрашивает или пайплайн уведомляет по завершении.

Продолжение вебхука

Шлюз Inquir подтверждает Stripe или GitHub в таймауте провайдера, тяжёлая работа — в шаге пайплайна. Повторы провайдера не перезапускают дорогостоящую работу.

Cron шире vercel.json

Ночной ETL, ротация токенов и отчёты работают как cron-пайплайны Inquir с видимой историей и ретраями на уровне шага — не хрупкий Route Handler за cron-хитом Vercel.

Как подключить Next.js к пайплайнам Inquir

Server Actions и Route Handlers остаются тонкими: валидация, enqueue в Inquir, ответ клиенту. Пайплайны несут повторы, секреты и историю для медленного пути.

1

Вынести медленную логику в функцию Inquir

Email, PDF или sync — в handler Inquir или шаг пайплайна. Входы явные; обработчики идемпотентны, чтобы ретраи были безопасны.

2

Enqueue из Server Action или Route Handler

fetch URL шлюза Inquir с Authorization: Bearer из process.env.INQUIR_API_KEY. Верните 202 или редирект до завершения пайплайна.

3

Смотреть историю выполнения в Inquir

Каждый запуск, retry и сбой — в Inquir, без поиска по логам Vercel Function за работой, начатой в Server Action или after().

Next.js Server Action → Inquir: enqueue после отправки формы

Server Action валидирует форму и передаёт работу в шлюз Inquir. Шлюз ставит durable job и возвращает 202. Шаг пайплайна создаёт файл и уведомляет приложение. Пользователь видит успех сразу; медленная работа выполняется вне любого таймаута Next.js или Vercel.

app/actions/request-export.ts (App Router Server Action)
'use server';

export async function requestExport(formData: FormData) {
  const exportId = formData.get('exportId') as string;
  if (!exportId) throw new Error('exportId required');

  // Hand off to Inquir — returns before the pipeline finishes
  const res = await fetch(process.env.INQUIR_GATEWAY_URL + '/jobs/run-export', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      Authorization: `Bearer ${process.env.INQUIR_API_KEY}`,
    },
    body: JSON.stringify({ exportId }),
  });
  if (!res.ok) throw new Error('Failed to queue export');
  // Server Action returns; user sees success — Inquir runs the slow work
}
inquir/gateway-run-export.mjs (Inquir HTTP gateway handler)
export async function handler(event) {
  const { exportId } = JSON.parse(event.body || '{}');
  if (!exportId) {
    return { statusCode: 400, body: JSON.stringify({ error: 'exportId required' }) };
  }
  // Queue a durable job; pipeline step runs outside the HTTP window
  const { instanceId: jobId } = await global.durable.startNew('run-export', undefined, { exportId });
  return { statusCode: 202, body: JSON.stringify({ jobId, status: 'queued' }) };
}
inquir/run-export.mjs (Inquir pipeline step)
export async function handler(event) {
  // event.payload carries the body the Server Action sent
  const { exportId } = event.payload ?? {};
  const file = await buildExport(exportId);
  await storage.put(`exports/${exportId}.csv`, file);
  await notifyApp(exportId, file.byteLength);
  return { exportId, bytes: file.byteLength };
}

Когда нужен пайплайн Inquir

Когда это уместно

  • Побочный эффект в Server Action или Route Handler может упасть независимо, нужны повторы или он выходит за таймаут платформы.
  • Нужны cron-задачи, продолжение вебхуков или параллельный fan-out с видимой историей рядом с кодом App Router.

Когда лучше выбрать другое

  • Вся фоновая работа укладывается в after() или Fluid Compute и не нужна история job между запросами или ретраи на уровне шага.

Вопросы и ответы

Заменять ли after() на Inquir?

Не всегда. after() — для быстрой работы после ответа внутри таймаута платформы. Inquir — когда job может упасть отдельно, нужны ретраи, расписание или жизнь дольше вызова функции.

Можно ли оставить Next.js на Vercel?

Да. Страница про примитивы Next.js, не про смену хостинга. Vercel — для App Router и edge; Inquir — worker-уровень.

Чем отличается от «фоновых задач для Vercel»?

Страница о Vercel описывает фреймворк-агностичную топологию для Next.js, SvelteKit, Nuxt, Astro. Эта страница фокусируется на API Next.js — after(), Server Actions, Route Handlers — и точке отказа каждого примитива.

Нужна ли отдельная очередь вроде BullMQ?

Нет. Пайплайны Inquir дают очередь, повторы и наблюдаемость. Next.js вызывает шлюз; Inquir управляет остальным.