IHOR.DEVБАЗА_ЗНАНЬ
МЕНЮ

~/blog / Вебстек / type-safe-route-handlers-in-next-js.md

// посібник · 2 хв читання

Типобезпечні обробники маршрутів у Next.js

Створюйте Next.js Route Handlers із unknown-входом, runtime-схемами, авторизованими операціями, типами відповіді й точними HTTP-статусами.

Коротка відповідь

Типізований handler перевіряє HTTP на runtime: unknown, malformed/invalid input, identity й дозвіл, явна відповідь. TypeScript перевіряє код, не відповідність request.json. Parsing, authorization, domain-work і HTTP-проєкція розділені.

Практичні кроки реалізації

1. Визначте джерела входів

Path, query, headers і body — окремі входи з форматами й межами. Перевіряйте відсутні та повторні query. Next.js 16 params — promise, потрібен await. Визначте JSON і body-limit; Content-Length не обмежує chunked чи неправдивий запит.

2. Відокремте синтаксис від домену

JSON-parse відрізняється від invalid-name чи amount. Поверніть послідовний documented client-error без приватного echo. Схема чи guard перевіряє типи й межі. Coercion свідомий: string "false" не означає Boolean false.

3. Авторизуйте окремо від parsing

Валідний ID не є дозволом. Використайте серверну сесію й tenant, потім операцію. Unauthenticated, denied, missing, conflict і upstream-failure не є успішним порожнім об’єктом. Browser-route має відповідний origin/request-захист.

Приклад реалізації

Демонстрація публічного normalize-endpoint не має side effect. Відхиляє malformed JSON і повертає проєкцію. Write додає auth, permissions, limits, rate-policy й domain-operation. Guard не вважає cast доказом.

// app/api/normalize-name/route.ts
type Input = { name: string };
type Output = { name: string };

function isInput(value: unknown): value is Input {
  return typeof value === "object" && value !== null &&
    "name" in value && typeof value.name === "string" &&
    value.name.trim().length >= 2 && value.name.trim().length <= 80;
}

export async function POST(request: Request) {
  let value: unknown;
  try { value = await request.json(); }
  catch { return Response.json({ error: "Malformed JSON" }, { status: 400 }); }
  if (!isInput(value)) {
    return Response.json({ error: "Invalid name" }, { status: 400 });
  }
  const result: Output = { name: value.name.trim() };
  return Response.json(result);
}

Компроміси та альтернативи

Schema-library дає повторну валідацію, small guard — ясність малого контракту. Generated-types не перевіряють runtime. Route Handler потрібен HTTP-клієнтам; Server Component може викликати underlying-reader напряму без self-HTTP.

Поширені помилки

Уникайте casts body, identity із входу, повних DB-records і exceptions у 200. page.tsx і route.ts не на одному segment. Public GET не автоматично cached: конфігурація й модель важливі. Не log tokens чи повний private-payload.

Перевірка перед випуском

  • Усі зовнішні входи мають runtime-перевірку.
  • Body-limits і формат визначено.
  • Приватні операції перевіряють доступ.
  • HTTP-помилки відповідають контракту.
  • Відповіді й logs містять потрібні поля.

Поширені запитання

Чи response-type перевіряє викликача?

Ні. Він перевіряє створення відповіді кодом. Вхід і identity перевіряються окремо.

Чи всюди потрібен NextRequest?

Стандартного Request достатньо за потрібних API. NextRequest додає nextUrl і cookies, не змінює довіру.

Наступний крок

Опишіть вхід, дозвіл, успіх і відмови маршруту. Перевірте malformed, denied і upstream до shared-types. Повторюйте доменну функцію, HTTP-рішення залиште на межі.

Первинні джерела

Пов’язані матеріали та приклади

Ігор Харчишин

Незалежний full-stack інженер продуктів, який пише посібники з реалізації розширень браузера та сучасних вебпродуктів на основі першоджерел.

Потрібно реалізувати це у вашому продукті?

Перегляньте відповідні приклади продуктів або поділіться контекстом розробки вебзастосунку, розширення Chrome, API чи SaaS.