typescriptintermediate

Next.js Route Handlers (API Routes)

Build RESTful API endpoints using Next.js App Router route handlers with typed responses.

typescript
// app/api/posts/route.ts
import { NextRequest, NextResponse } from 'next/server';

interface Post {
  id: string;
  title: string;
  content: string;
}

const posts: Post[] = [];

// GET /api/posts?page=1&limit=10
export async function GET(request: NextRequest) {
  const { searchParams } = request.nextUrl;
  const page = parseInt(searchParams.get('page') || '1');
  const limit = parseInt(searchParams.get('limit') || '10');

  const start = (page - 1) * limit;
  const paginated = posts.slice(start, start + limit);

  return NextResponse.json({
    data: paginated,
    total: posts.length,
    page,
    limit,
  });
}

// POST /api/posts
export async function POST(request: NextRequest) {
  const body = await request.json();

  if (!body.title || !body.content) {
    return NextResponse.json(
      { error: 'Title and content are required' },
      { status: 400 }
    );
  }

  const post: Post = {
    id: crypto.randomUUID(),
    title: body.title,
    content: body.content,
  };
  posts.push(post);

  return NextResponse.json(post, { status: 201 });
}

// app/api/posts/[id]/route.ts
export async function GET(
  request: NextRequest,
  { params }: { params: { id: string } }
) {
  const post = posts.find((p) => p.id === params.id);
  if (!post) {
    return NextResponse.json({ error: 'Not found' }, { status: 404 });
  }
  return NextResponse.json(post);
}

export async function DELETE(
  request: NextRequest,
  { params }: { params: { id: string } }
) {
  const index = posts.findIndex((p) => p.id === params.id);
  if (index === -1) {
    return NextResponse.json({ error: 'Not found' }, { status: 404 });
  }
  posts.splice(index, 1);
  return new NextResponse(null, { status: 204 });
}

Use Cases

  • Building REST APIs within a Next.js application
  • Webhook endpoints for third-party integrations
  • Backend-for-frontend API layer

Tags

Related Snippets

Similar patterns you can reuse in the same workflow.