⚡ TECH BLOG
Home
Blog
Tags
About
⚡

Powered by Next.js 15 & Modern Web Tech ⚡

Back to Home

Next.js API Routes: Building Serverless APIs

October 15, 2022
nextjsapiserverlessnodejs
Next.js API Routes: Building Serverless APIs

Next.js API Routes: Building Serverless APIs

Next.js API routes allow you to build APIs within your Next.js application. Let's explore how to create powerful serverless endpoints.

Basic API Route

// pages/api/hello.ts
import type { NextApiRequest, NextApiResponse } from 'next';

export default function handler(
  req: NextApiRequest,
  res: NextApiResponse
) {
  res.status(200).json({ message: 'Hello from API!' });
}

HTTP Methods

// pages/api/users/index.ts
import type { NextApiRequest, NextApiResponse } from 'next';

export default async function handler(
  req: NextApiRequest,
  res: NextApiResponse
) {
  switch (req.method) {
    case 'GET':
      const users = await getUsers();
      res.status(200).json(users);
      break;
    
    case 'POST':
      const user = await createUser(req.body);
      res.status(201).json(user);
      break;
    
    default:
      res.setHeader('Allow', ['GET', 'POST']);
      res.status(405).end(`Method ${req.method} Not Allowed`);
  }
}

Dynamic Routes

// pages/api/users/[id].ts
import type { NextApiRequest, NextApiResponse } from 'next';

export default async function handler(
  req: NextApiRequest,
  res: NextApiResponse
) {
  const { id } = req.query;
  
  if (req.method === 'GET') {
    const user = await getUserById(id as string);
    
    if (!user) {
      return res.status(404).json({ error: 'User not found' });
    }
    
    res.status(200).json(user);
  }
}

Middleware

// middleware.ts
import type { NextApiRequest, NextApiResponse } from 'next';

type Middleware = (
  req: NextApiRequest,
  res: NextApiResponse,
  next: () => void
) => void;

function withMiddleware(middleware: Middleware[]) {
  return (handler: Function) => {
    return async (req: NextApiRequest, res: NextApiResponse) => {
      for (const mw of middleware) {
        await new Promise<void>((resolve, reject) => {
          mw(req, res, () => resolve());
        });
      }
      return handler(req, res);
    };
  };
}

// Auth middleware
const authMiddleware = (
  req: NextApiRequest,
  res: NextApiResponse,
  next: () => void
) => {
  const token = req.headers.authorization;
  
  if (!token) {
    return res.status(401).json({ error: 'Unauthorized' });
  }
  
  next();
};

// Usage
export default withMiddleware([authMiddleware])(handler);

Error Handling

// pages/api/users/index.ts
import type { NextApiRequest, NextApiResponse } from 'next';

export default async function handler(
  req: NextApiRequest,
  res: NextApiResponse
) {
  try {
    const users = await getUsers();
    res.status(200).json(users);
  } catch (error) {
    console.error(error);
    res.status(500).json({ error: 'Internal Server Error' });
  }
}

App Router API Routes (Next.js 13+)

// app/api/users/route.ts
import { NextResponse } from 'next/server';

export async function GET() {
  const users = await getUsers();
  return NextResponse.json(users);
}

export async function POST(request: Request) {
  const body = await request.json();
  const user = await createUser(body);
  return NextResponse.json(user, { status: 201 });
}

Best Practices

  1. Validate input with libraries like Zod
  2. Handle errors gracefully
  3. Use TypeScript for type safety
  4. Implement rate limiting
  5. Keep routes focused - single responsibility

Conclusion

Next.js API routes provide a powerful way to build serverless APIs alongside your frontend. With proper structure and error handling, you can create robust APIs for your applications.

Share:

💬 Comments