Body parsing і validation у Bun.js: JSON, uploads, streams і payload limits
Практичний deep dive по body parsing middleware у Bun.js: JSON, FormData, uploads, streams, payload limits, schema validation, idempotency, content-type checks, безпечний порядок middleware і погані практики.

Bun.js Middleware Production Guide 2026
Серія про production middleware у Bun.js: огляд, безпека, performance, observability, rate limiting, body parsing, WebSocket/SSE і тестування request pipeline.
Усі статті в цьому гайді
01
Bun.js middleware у 2026: overview, best practices і анти-патерни
Базова ментальна модель middleware у native Bun, Hono та Elysia, з прикладами, оптимізацією і roadmap наступних deep dive статей.
02
Auth middleware у Bun.js: JWT, sessions, API keys і multi-tenant контекст
Як правильно будувати auth middleware у Bun: порядок перевірок, cache, token rotation, tenant context, помилки 401/403 і тестування.
03
Rate limiting у Bun.js: in-memory, Redis, sliding window і edge cases
Детальний розбір rate limiting для Bun API: алгоритми, Redis, distributed limits, abuse protection і graceful degradation.
04
Observability middleware у Bun.js: logs, request id, tracing і latency budgets
Як додати request id, structured logs, timing headers, OpenTelemetry-подібний flow і не перетворити логування на bottleneck.
05
Body parsing і validation у Bun.js: JSON, uploads, streams і payload limits
Як безпечно читати body у Bun, де ставити limits, як не зламати streams, uploads, idempotency і schema validation.
У Bun, як і в Web API загалом, request body не є безкінечною змінною, яку можна читати скільки завгодно. Це stream. Якщо один шар прочитав його без договору з рештою pipeline, наступний шар може отримати порожній body, помилку або неочікувану поведінку.
Саме тому body parsing не варто ховати в глобальний middleware “про всяк випадок”. Він має бути route-aware, content-type aware і size-aware.
У цій статті розбираємо, як зробити parsing і validation так, щоб вони захищали API, а не створювали memory pressure, security holes і дивні баги.
Це фінальний chapter поточного roadmap по Bun middleware. Він закриває тему request body - найчастіше джерело memory, security і validation проблем у API.
req.json(), body logs, parsing після auth/rate limit у неправильному порядку, validation без strip/strict policy.Найважливіше правило: request body має одного власника. Якщо кілька middleware намагаються читати body самостійно, pipeline стає крихким.
Перевірити route і method
Не читайте body для GET/HEAD або routes, де body не потрібен. Це економить latency і прибирає випадкові side effects.
Перевірити content-type
JSON route має приймати application/json, upload route - multipart/form-data або конкретний binary content-type. Не парсіть усе як JSON.
Застосувати size limit
Якщо ліміт перевіряється після await req.json() або await req.formData(), він уже не захищає пам'ять від великого payload.
Прочитати body один раз
Використовуйте json(), formData(), arrayBuffer() або stream залежно від route. Parsed value передавайте в context.
Валідувати і передати typed value
Schema validation має повертати типізований результат або стабільний 400/422, а не залишати handler здогадуватись.
Висновок
Body ownership робить pipeline передбачуваним: handler отримує готовий parsed value, а не сам вирішує, що сталося з stream.
Bun HTTP server працює з Web Request/Response моделлю. Тому базові методи body reading знайомі з Fetch API: json(), text(), formData(), arrayBuffer(), blob() і stream. [1][2]
| Метод | Коли використовувати | Що повертає | Головна обережність |
|---|---|---|---|
req.json() | JSON API, webhook JSON, config mutations | Parsed JavaScript value | Падає на invalid JSON, потребує size/content-type/schema checks |
req.formData() | Forms, multipart uploads, mixed text/file fields | FormData з fields/files | Може буферизувати великі upload-и, потрібні file limits і storage policy |
req.arrayBuffer() | Binary payload, signatures, raw webhook verification | ArrayBuffer | Може різко збільшити memory pressure на великих payloads |
req.text() | Plain text, raw signature input, small text payloads | String | Не підходить для великих streams або uploads |
req.body stream | Великі payload-и, streaming ingestion, custom parsers | ReadableStream або null | Потрібно самому контролювати backpressure, limits і errors |
Вибір body API має залежати від route. JSON, FormData, binary і streams не треба пропускати через один універсальний parser.
Скріншот секції request-body-apisВисновок
Універсальний body parser зручний на старті, але production API краще розділяти за content-type і route purpose.
Для JSON routes вам потрібен не просто await req.json(), а маленький gate: перевірити content-type, приблизний content-length, прочитати body, обробити parse errors, провалідовати schema, передати typed result.
Мінімальний native Bun патерн:
type JsonContext<T> = { body: T };
type JsonHandler<T> = (req: Request, ctx: JsonContext<T>) => Promise<Response> | Response;
function jsonRoute<T>(schema: { parse: (value: unknown) => T }, handler: JsonHandler<T>) {
return async (req: Request) => {
const contentType = req.headers.get("content-type") ?? "";
if (!contentType.includes("application/json")) {
return Response.json({ error: "unsupported_media_type" }, { status: 415 });
}
const contentLength = Number(req.headers.get("content-length") ?? 0);
if (contentLength > 256_000) {
return Response.json({ error: "payload_too_large" }, { status: 413 });
}
try {
const raw = await req.json();
const body = schema.parse(raw);
return handler(req, { body });
} catch {
return Response.json({ error: "invalid_request_body" }, { status: 400 });
}
};
}У реальному коді краще розділити parse error і validation error, щоб повертати 400 для invalid JSON і 422 для schema mismatch, якщо ваш API contract це підтримує. Але головне - handler уже не читає body сам.
Практичне правило
JSON middleware має створювати typed body context. Якщо handler знову викликає req.json(), ownership не працює.
File upload - одна з найризикованіших поверхонь API. OWASP File Upload Cheat Sheet радить обмежувати extension, перевіряти content type, змінювати filename, задавати size limits, зберігати файли поза webroot, перевіряти permissions і за потреби сканувати файли. [4]
У Bun upload route не має проходити через той самий JSON middleware. Upload потребує окремих правил: що можна завантажувати, який максимум, куди зберігати, як називати, коли сканувати, чи потрібна асинхронна обробка.
Важливо відрізняти metadata validation від file validation. Поля форми можна валідовувати schema, але файл треба перевіряти окремо: size, declared MIME, magic bytes, extension allowlist, malware scanning, storage path.
Upload route має окремий pipeline: size limit, type allowlist, scan/validation і безпечне storage рішення.
Скріншот секції uploadsЯкщо route приймає великий payload, ingestion stream, media upload або long-running transfer, arrayBuffer() і formData() можуть бути неправильним вибором. Вони зручні, але можуть змусити runtime тримати значний обсяг даних у пам'яті.
Streaming flow вимагає іншого мислення: ранні limits, backpressure, abort handling, timeout policy, storage streaming, partial failures і cleanup. Це не “звичайний JSON endpoint з великим body”.
Для streams observability теж інша: total request time може бути довгим і нормальним, тому важливо міряти throughput, bytes accepted, time to first byte, storage errors і client aborts.
Великі payload-и треба stream-ити через pipeline, а не перетворювати на один великий buffer заради зручності handler.
Скріншот секції streamsВисновок
Як тільки payload може бути великим, body parsing стає performance і reliability темою, а не просто validation helper.
Schema validation має не тільки перевірити типи. Вона має визначити, що робити з невідомими полями, coercion, defaults і partial updates.
Strict schema
Добре для security-sensitive API: невідомі поля відхиляються. Мінус - клієнти можуть ламатися при зайвих полях.
Strip unknown
Зручно для public API: зайві поля відкидаються, business logic бачить чистий shape. Важливо логувати schema mismatch обережно.
Passthrough
Корисно тільки коли API справді приймає dynamic payload. Інакше це створює ризик mass assignment або прихованих полів.
Coercion everywhere
Автоматичне перетворення типів може бути зручним, але іноді приховує помилки клієнта. Для money, permissions і security flags краще бути суворішим.
Висновок
Validation policy має бути частиною API contract. Якщо кожен route трактує unknown fields по-своєму, клієнти і security review швидко втрачають передбачуваність.
POST/PUT flows з оплатою, замовленнями, webhook retries, file ingestion і background jobs мають окрему проблему: клієнт може повторити request, бо не отримав response або отримав timeout. Body validation тут має працювати разом з idempotency key.
Idempotency middleware зазвичай перевіряє Idempotency-Key, route group, subject/tenant і hash body. Якщо той самий key приходить з іншим body, це має бути conflict, а не повторне виконання mutation.
Це не обов'язково для кожного JSON route, але для дорогих або irreversible operations це часто дешевше, ніж розбирати дублікати в бізнес-даних після інциденту.
Практичне правило
Якщо mutation небезпечно виконати двічі, body validation має включати idempotency story.
Ці помилки найчастіше з'являються, коли команда намагається зробити “універсальний body middleware” для всього API.
Глобальний await req.json() для всіх routes.
Читання body у кількох middleware без передачі parsed context.
Payload limit після parsing, а не до нього.
Один parser для JSON, multipart, binary і streams.
Логування raw body у production.
Відсутній 415 Unsupported Media Type для неправильного content-type.
Uploads зберігаються з оригінальним filename у public директорію.
Validation пропускає unknown fields у security-sensitive endpoints.
Немає відмінності між invalid JSON (400) і schema mismatch (422), якщо API contract це потребує.
Large payload routes не мають timeout, abort і cleanup policy.
Рев'ю правило
Body parser має бути route-specific. Якщо він “працює для всього”, він майже точно не захищає важливі edge cases.
Перед запуском Bun API у staging або production пройдіть цей список для кожного класу endpoint: JSON, upload, stream, webhook і mutation.
Body owner визначений
Один middleware або route-level gate читає body і передає parsed context.
Content-type перевіряється
JSON, multipart, binary і streams мають різні accepted content-types.
Size limit стоїть рано
Ліміт застосовується до parsing або streaming ingestion, а не після повного buffer.
Schema validation має policy
Strict, strip або passthrough поведінка зафіксована і однакова для route class.
Uploads мають security controls
Extension/MIME allowlist, size limits, safe filename, storage policy, permissions і scanning за потреби.
Streams мають abort/cleanup
Client abort, timeout, partial writes і storage errors обробляються явно.
Errors стабільні
400, 413, 415, 422 і 500 мають прогнозований JSON contract.
Body не логиться
У logs йде request id, route, status, validation error class, але не raw body або file contents.
Bun дає зручну Web Request/Response модель, але саме тому легко забути, що body - це stream, а не звичайний object. Добрий middleware не читає body “про всяк випадок”. Він знає route, method, content-type, size limit і schema.
JSON, uploads, streams і binary payloads потребують різних pipelines. У production універсальний parser часто стає джерелом memory pressure, validation ambiguity і security risk.
Найкращий підхід простий: один власник body, ранній limit, правильний parser, typed validation result, стабільний error contract і окрема upload/stream policy. Це закриває більшість проблем ще до handler.
Не варто. Request body є stream, і його треба читати один раз у відповідальному шарі. Parsed value передавайте в context або handler. Повторне читання без контракту створює крихкі bugs.
Якомога раніше: до дорогого parsing або під час streaming ingestion. Якщо ви спочатку робите `await req.json()` або `await req.formData()`, великий payload уже потрапив у пам'ять.
Для production краще ні. JSON, multipart uploads, binary і streams мають різні security, memory і validation вимоги. Їх треба розділяти по route classes.
`400` для invalid syntax або malformed body, `413` для завеликого payload, `415` для неправильного content-type, `422` для schema mismatch, якщо ваш API contract розрізняє validation errors.
Ні за замовчуванням. Логуйте request id, route, error class, field names або safe summary. Raw body може містити PII, credentials або великі payload-и.
Для mutations, які небезпечно виконати двічі: payments, orders, uploads, webhook processing, job creation. Idempotency key має бути пов'язаний із subject/tenant/route і hash body.
Джерела підтверджують Web Request body methods, Bun HTTP server model і security baseline для uploads та content validation.
PAS7 Studio може допомогти спроєктувати validation pipeline для Bun, Hono або Elysia: JSON schemas, upload security, payload limits, stream ingestion, idempotency keys, stable error contract і observability.
Це особливо корисно для SaaS, webhook endpoints, file ingestion, AI/automation flows і міграцій з Express/Fastify, де body parsing часто розкиданий по middleware, handlers і validators.
Body parsing і validation у Bun.js: JSON, uploads, streams і payload limits
Ви тут: 05/05
Body parsing і validation у Bun.js: JSON, uploads, streams і payload limits
Пов'язані статті
Скільки коштує розробка AI асистента у 2026: RAG чатбот, база знань, CRM, Telegram та підтримка
Практичний гід для бізнесу: від чого залежить ціна розробки AI асистента у 2026 році, що входить у RAG чатбот, інтеграції з CRM, Telegram, guardrails, оцінювання, моніторинг і супровід.
AI для розробки лендінгів: де він реально прискорює запуск, а де псує конверсію
Дослідження про використання AI у розробці лендінгів: v0, Webflow AI, Builder.io, Framer-подібні AI builders, генерація UX, copy, SEO, персоналізація, A/B тести, ризики шаблонності, безпеки, доступності та технічного боргу.
AI SEO / GEO у 2026: ваші наступні клієнти — не люди, а агенти
Пошук зміщується від кліків до відповідей. Боти та AI-агенти сканують, цитують, рекомендують і дедалі частіше купують. Дізнайтесь, що таке AI SEO / GEO, чому класичного SEO вже недостатньо, і як PAS7 Studio допомагає брендам перемагати у «агентному» вебі.
Найпотужніший чіп від Apple? M5 Pro і M5 Max б'ють рекорди
Аналітичний розбір Apple M5 Pro і M5 Max станом на березень 2026 року. Пояснюємо, чому ці чіпи можна вважати найпотужнішими професійними ноутбучними SoC від Apple, як вони виглядають на тлі M4 Pro, M4 Max, M1 Pro, M1 Max і що показують у порівнянні з актуальними Intel та AMD.
Професійна розробка для вашого бізнесу
Створюємо сучасні веб-рішення та боти для бізнесу. Дізнайтеся, як ми можемо допомогти вам досягти цілей.