Next.js API Routes and Middleware
Create serverless API endpoints in the api/ directory, process requests in Route Handlers, and run edge Middleware for auth and redirects.
Next.js API Routes and Middleware is a free Frontend Academy lesson on CoddyKit — lesson 4 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the Frontend Academy learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.
Why API Routes?
Next.js bundles a server with your app — you can write backend endpoints alongside your pages without a separate Node project. Great for proxying, form submissions, webhooks, and small APIs.
Pages Router API Routes
Files in pages/api/ export a default function with Express-style (req, res).
// pages/api/users.ts
import type { NextApiRequest, NextApiResponse } from 'next';
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
if (req.method === 'GET') {
const users = await db.users.findMany();
return res.json(users);
}
if (req.method === 'POST') {
const user = await db.users.create({ data: req.body });
return res.status(201).json(user);
}
return res.status(405).end();
}App Router Route Handlers
App Router uses the Web standard Request/Response API. Each HTTP method is a named export.
// app/api/users/route.ts
import { NextResponse } from 'next/server';
export async function GET() {
const users = await db.users.findMany();
return NextResponse.json(users);
}
export async function POST(request: Request) {
const body = await request.json();
const user = await db.users.create({ data: body });
return NextResponse.json(user, { status: 201 });
}Dynamic API Routes
Dynamic segments work the same: app/api/users/[id]/route.ts matches /api/users/123.
// app/api/users/[id]/route.ts
export async function GET(req: Request, { params }: { params: { id: string }}) {
const user = await db.users.findUnique({ where: { id: params.id }});
if (!user) return new Response('Not Found', { status: 404 });
return Response.json(user);
}Reading Cookies and Headers
In App Router, use the helpers from next/headers (request-scoped).
import { cookies, headers } from 'next/headers';
export async function GET() {
const token = cookies().get('token')?.value;
const userAgent = headers().get('user-agent');
// ...
}Streaming Responses
Route handlers can return a streaming response — useful for AI chat completions or large file generation.
export async function GET() {
const encoder = new TextEncoder();
const stream = new ReadableStream({
async start(controller) {
for (let i = 0; i < 5; i++) {
controller.enqueue(encoder.encode(`chunk ${i}\n`));
await new Promise(r => setTimeout(r, 500));
}
controller.close();
}
});
return new Response(stream);
}Middleware — Run Before Routes
middleware.ts at the project root runs before requests reach pages or API routes. Use it for auth checks, redirects, header rewriting, A/B testing.
// middleware.ts
import { NextResponse, type NextRequest } from 'next/server';
export function middleware(request: NextRequest) {
const token = request.cookies.get('token');
if (!token && request.nextUrl.pathname.startsWith('/dashboard')) {
return NextResponse.redirect(new URL('/login', request.url));
}
return NextResponse.next();
}Middleware Matcher
Limit which paths the middleware runs on with a matcher config.
export const config = {
matcher: [
'/dashboard/:path*',
'/api/:path*',
'/((?!_next/static|_next/image|favicon.ico).*)'
]
};Middleware Runtime
Middleware runs on Edge Runtime by default — a lightweight V8 isolate (not full Node). Available APIs are limited: no Node modules like fs, no native deps.
Auth Pattern with Middleware
Common: verify a JWT in middleware, redirect to login if missing/invalid, attach decoded user to a request header that downstream routes can read.
import jwt from 'jsonwebtoken';
export function middleware(req: NextRequest) {
const token = req.cookies.get('token')?.value;
if (!token) return NextResponse.redirect(new URL('/login', req.url));
try {
const decoded = jwt.verify(token, process.env.SECRET!);
const res = NextResponse.next();
res.headers.set('x-user-id', String(decoded.sub));
return res;
} catch {
return NextResponse.redirect(new URL('/login', req.url));
}
}Rate Limiting in Middleware
Combine middleware with a KV store (Upstash, Vercel KV) to enforce per-IP rate limits before hitting your API logic.
When NOT to Use API Routes
For separate microservices or shared APIs, deploy a real backend (Hono, Express, NestJS). Next.js API routes shine for proxying, webhooks, and app-specific endpoints — not for serving a public API to other clients.
Quick Check
Where does Next.js middleware run, and what's the most common use case?
Recap: API Routes & Middleware
Pages Router: pages/api with req/res. App Router: app/api/.../route.ts with method exports (GET/POST/etc.) using Request/Response. Read cookies/headers via next/headers. Streaming responses with ReadableStream. middleware.ts runs on Edge before routes — auth, redirects, headers. Matcher config limits paths. Use real backend for public APIs.
Frequently asked questions
Is the “Next.js API Routes and Middleware” lesson free?
Yes — the full text of “Next.js API Routes and Middleware” is free to read here on the web, and the Frontend Academy course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the Frontend Academy course, upgrade to CoddyKit PRO.
What will I learn in “Next.js API Routes and Middleware”?
Create serverless API endpoints in the api/ directory, process requests in Route Handlers, and run edge Middleware for auth and redirects. You practise Frontend Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.
Do I need any experience to start Frontend Academy?
No prior experience is required. Frontend Academy on CoddyKit is structured for beginners through advanced learners; this is — lesson 4 of 4, so you can start here or from the beginning and move at your own pace.
How long does the “Next.js API Routes and Middleware” lesson take?
Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.
Can I write and run code in this Frontend Academy lesson?
Yes. Every Frontend Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.
All lessons in this course
- Pages Router vs App Router
- Server Components and Client Components
- SSG SSR and ISR
- Next.js API Routes and Middleware