Next.js has revolutionized modern web development by blending the best of server–side and client–side rendering. One of the most significant changes introduced with the App Router is the transformation of how API routes are defined, structured, and deployed.
With Next.js 14, developers can now build robust, RESTful, and scalable APIs directly inside the /app directory, tightly integrated with their UI. This approach simplifies full–stack development while leveraging the performance benefits of serverless functions.
In this article, we’ll dive into the new API routing capabilities introduced in the App Router and show how to design performant and secure APIs within your React application.
🗂️ File–Based Routing for RESTful API Endpoints
With the App Router, your API routes now live inside the /app/api/ folder and are defined using the HTTP verb naming convention inside route.ts or route.js files.
Example: Creating a GET and POST endpoint
// app/api/users/route.ts
import { NextResponse } from ‘next/server’
export async function GET() {
const users = await fetchUsersFromDB()
return NextResponse.json(users)
}
export async function POST(request: Request) {
const body = await request.json()
const createdUser = await createUser(body)
return NextResponse.json(createdUser, { status: 201 })
}
Each route.ts can handle multiple HTTP methods (GET, POST, PUT, DELETE, etc.), and it automatically becomes a serverless function.
🛡️ Middleware for Authentication and Headers
Security is critical for API routes. With middleware support in the App Router, you can enforce auth checks or manipulate headers before requests hit your endpoints.
Example: Require JWT authentication across all /api routes
// middleware.ts
import { NextResponse } from ‘next/server’
import type { NextRequest } from ‘next/server’
export function middleware(request: NextRequest) {
const token = request.cookies.get(‘auth_token’)
if (!token) {
return NextResponse.redirect(new URL(‘/login’, request.url))
}
return NextResponse.next()
}
export const config = {
matcher: [‘/api/:path*’],
}
With this setup, all API routes are protected unless a valid token is found in the cookies.
🌐 Handling CORS and API Versioning
If your Next.js app needs to serve APIs to third–party clients (e.g., mobile apps or external integrations), handling CORS (Cross–Origin Resource Sharing) correctly is essential.
Example: Enabling CORS for a specific API route
// app/api/public/route.ts
import { NextResponse } from ‘next/server’
export async function OPTIONS() {
return new NextResponse(null, {
status: 204,
headers: {
‘Access-Control-Allow-Origin’: ‘*’,
‘Access-Control-Allow-Methods’: ‘GET, POST, OPTIONS’,
‘Access-Control-Allow-Headers’: ‘Content-Type, Authorization’,
},
})
}
export async function GET() {
return NextResponse.json({ message: ‘CORS enabled’ }, {
headers: {
‘Access-Control-Allow-Origin’: ‘*’,
},
})
}
For versioning, consider a folder–based strategy:
/app/api/v1/users/route.ts
/app/api/v2/users/route.ts
This allows you to evolve your API without breaking existing consumers.
⚡ Serverless Optimization and Cold–Start Tips
Each API route in Next.js App Router is deployed as a serverless function on Vercel or any other compatible platform.
Tips for reducing cold–start latency:
Use Edge Functions for lightweight APIs (e.g., geo–based redirects or token checks)
Avoid cold–start heavy libraries in small endpoints (e.g., avoid initializing a DB client unless needed)
Use connection pooling for databases like PostgreSQL with libraries like pg–pool or Prisma Data Proxy
Example: Using Edge runtime for low–latency API
// app/api/geo/route.ts
export const runtime = ‘edge’
export async function GET() {
return new Response(JSON.stringify({ region: ‘EU’ }), {
headers: { ‘Content-Type’: ‘application/json’ },
})
}
👥 Who Should Use This?
This API approach is ideal for:
Full–stack developers building complete apps in React + Next.js
Teams replacing backend monoliths with microservices or serverless functions
SaaS platforms needing tightly integrated APIs and UI components
Projects migrating from external Express/Node APIs to a unified app structure