11 min read
ā¢Question 34 of 47hardAdvanced Route Handler Patterns
Complex API patterns with Route Handlers.
Advanced Route Handlers
Streaming Responses
code.txtTSX
// app/api/stream/route.ts
export async function GET() {
const encoder = new TextEncoder();
const stream = new ReadableStream({
async start(controller) {
for (let i = 0; i < 10; i++) {
await new Promise((r) => setTimeout(r, 1000));
controller.enqueue(encoder.encode(`data: ${i}\n\n`));
}
controller.close();
},
});
return new Response(stream, {
headers: {
'Content-Type': 'text/event-stream',
'Cache-Control': 'no-cache',
'Connection': 'keep-alive',
},
});
}File Uploads
code.txtTSX
// app/api/upload/route.ts
import { writeFile } from 'fs/promises';
import { join } from 'path';
export async function POST(request: Request) {
const formData = await request.formData();
const file = formData.get('file') as File;
const bytes = await file.arrayBuffer();
const buffer = Buffer.from(bytes);
const path = join(process.cwd(), 'uploads', file.name);
await writeFile(path, buffer);
return Response.json({ success: true });
}Rate Limiting
code.txtTSX
import { headers } from 'next/headers';
const rateLimit = new Map();
export async function GET() {
const headersList = headers();
const ip = headersList.get('x-forwarded-for') || 'anonymous';
const now = Date.now();
const windowMs = 60000; // 1 minute
const maxRequests = 10;
const requests = rateLimit.get(ip) || [];
const recentRequests = requests.filter((t: number) => now - t < windowMs);
if (recentRequests.length >= maxRequests) {
return Response.json(
{ error: 'Too many requests' },
{ status: 429 }
);
}
rateLimit.set(ip, [...recentRequests, now]);
return Response.json({ data: 'success' });
}