Crash Courses · Basic
API Routes & Server Actions
Build backend endpoints and mutate data with Route Handlers and Server Actions.
11 min read+150 XP on completionCert: Next.js Crash Course
Tap any word in the text below to start reading from there.
API Routes & Server Actions
Route Handlers are the App Router's API layer. Server Actions are the preferred mutation pattern — they eliminate the need for a separate API endpoint for most form submissions.
Route Handler
// app/api/courses/route.ts
import { NextRequest, NextResponse } from 'next/server'
import { COURSES } from '@/lib/courses'
export async function GET(req: NextRequest) {
const track = req.nextUrl.searchParams.get('track')
const courses = track
? COURSES.filter(c => c.track === track)
: COURSES
return NextResponse.json(courses)
}
export async function POST(req: NextRequest) {
const body = await req.json()
// validate and save...
return NextResponse.json({ success: true }, { status: 201 })
}Dynamic Route Handler
// 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: 'Not found' }, { status: 404 })
}
return NextResponse.json(course)
}Server Action
// app/actions/progress.ts
'use server'
import { revalidatePath } from 'next/cache'
export async function markComplete(courseId: string) {
// save to DB...
revalidatePath('/courses')
return { success: true }
}
// app/components/CompleteButton.tsx
'use client'
import { markComplete } from '@/app/actions/progress'
export function CompleteButton({ courseId }: { courseId: string }) {
return (
<button onClick={() => markComplete(courseId)}>
Mark Complete
</button>
)
}Reading progress
0% read
In this module
Route Handler
Server Action
revalidatePath
NextRequest
0%