Crash Courses · Basic
Building REST APIs in Next.js
Build fully typed REST API routes with Next.js Route Handlers.
11 min read+150 XP on completionCert: REST APIs Crash Course
Tap any word in the text below to start reading from there.
Building REST APIs in Next.js
Next.js Route Handlers implement REST endpoints. Zod validates input; NextResponse formats output.
Collection Route
// app/api/courses/route.ts
import { NextRequest, NextResponse } from 'next/server'
import { z } from 'zod'
import { COURSES } from '@/lib/courses'
export async function GET(req: NextRequest) {
const track = req.nextUrl.searchParams.get('track')
const level = req.nextUrl.searchParams.get('level')
let courses = COURSES
if (track) courses = courses.filter(c => c.track === track)
if (level) courses = courses.filter(c => c.level === level)
return NextResponse.json({
data: courses,
total: courses.length,
})
}
const CreateCourseSchema = z.object({
title: z.string().min(1).max(200),
track: z.string(),
xp: z.number().int().positive(),
duration: z.number().int().positive(),
})
export async function POST(req: NextRequest) {
try {
const body = await req.json()
const validated = CreateCourseSchema.parse(body)
// save to DB...
const course = await createCourse(validated)
return NextResponse.json({ data: course }, { status: 201 })
} catch (err) {
if (err instanceof z.ZodError) {
return NextResponse.json({ error: err.flatten() }, { status: 422 })
}
return NextResponse.json({ error: 'Internal server error' }, { status: 500 })
}
}Single Item Route
// app/api/courses/[id]/route.ts
export async function GET(
req: NextRequest,
{ params }: { params: Promise<{ id: string }> }
) {
const { id } = await params
const course = COURSES.find(c => c.id === id)
if (!course) {
return NextResponse.json({ error: 'Course not found' }, { status: 404 })
}
return NextResponse.json({ data: course })
}
export async function PATCH(
req: NextRequest,
{ params }: { params: Promise<{ id: string }> }
) {
const { id } = await params
const body = await req.json()
// partial update...
return NextResponse.json({ data: updated })
}
export async function DELETE(
req: NextRequest,
{ params }: { params: Promise<{ id: string }> }
) {
const { id } = await params
// delete...
return new NextResponse(null, { status: 204 })
}Reading progress
0% read
In this module
Route Handler
Zod validation
NextResponse.json()
params
0%