App Route Handlers: Web Standard Response Stream Piping
- Last updated
- Prerequisites:
- Web Streams API (ReadableStream, TransformStream)
- Fetch API Request/Response
- nextjs
- route-handlers
- web-streams
- streaming
- sse
- api
Read at your depth
The practical view
Next.js App Router uses `app/api/.../route.ts` files to create API endpoints. Instead of Node.js `(req, res)` callbacks, route handlers use standard Web `Request` and `Response` objects. You can return a `new Response(readableStream)` to stream text, AI tokens, or binary data chunk-by-chunk to the client with `Transfer-Encoding: chunked`.
The same idea in other frameworks
Standard Web Fetch API / Node `ReadableStream` response handling.NestJS `@Sse()` decorator or Express `res.write()` streaming.Nuxt 3 Nitro event handlers returning `sendStream()`.SvelteKit `+server.ts` returning a `new Response(stream)`.Legacy vs modern
Legacy Buffered JSON Response vs Web Stream Piping
Buffered responses force clients to wait for full completion; Web Streams send progressive text/tokens in real time.
res.status(200).json({ fullText }); // ❌ OLD: Waits for entire computationreturn new Response(stream, { headers: { 'Content-Type': 'text/event-stream' } }); // ✅ NEWInterview gotchas
Context
Interviewers test your knowledge of route handler evaluation rules.
The mechanical answer
In Next.js, a `GET` Route Handler is evaluated statically at build time by default if it does not access the `Request` object. To make it dynamic, you can export `export const dynamic恒 = 'force-dynamic'`, access request headers/cookies, or use other HTTP methods like `POST`, `PUT`, `DELETE`.
Trap
Do not assume all Route Handlers are dynamic. A parameter-less `GET` handler returning static data will be prerendered at build time.
Context
This tests knowledge of the transition to Web Standards in Next.js.
The mechanical answer
No. The App Router completely discarded the Express-like `(req, res)` signature in favor of Web Standards (`Request` in, `Response` or `NextResponse` out).
Trap
Avoid importing `NextApiResponse` in `app/api/.../route.ts` files; it only belongs in legacy `pages/api`.