Коротка відповідь
Типізований 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-рішення залиште на межі.
Первинні джерела
Пов’язані матеріали та приклади
Потрібно реалізувати це у вашому продукті?
Перегляньте відповідні приклади продуктів або поділіться контекстом розробки вебзастосунку, розширення Chrome, API чи SaaS.