API Routes

5 questions found

What are API routes in Next.js and why would you use them?

Beginner
API routes let you build backend endpoints directly inside your Next.js project, so you can handle things like form submissions or database calls without setting up a separate server. This keeps your frontend and backend code together in one project, which is convenient for small to medium sized applications.
// pages/api/hello.js (Pages Router)
export default function handler(req, res) {
  res.status(200).json({ message: 'Hello from the API' });
}
Real-world example A small business website uses an API route to receive contact form submissions and send them by email, avoiding the need to run a separate backend server just for this one feature.

Common follow-ups: How are API routes different from Route Handlers in the App Router?;Can API routes connect directly to a database?

Route Handlers (API Route.js);Data Fetching

How do you read query parameters and the request body inside an API route?

Beginner
In the Pages Router, the request object passed to your handler function gives you access to query parameters through req.query and to the submitted data through req.body, letting you build endpoints that respond differently based on what the client sent.
export default function handler(req, res) {
  const { id } = req.query;
  const { name } = req.body;
  res.status(200).json({ id, name });
}
Real-world example A product search API route reads a search term from the query string and returns matching products, letting the frontend build a live search feature.

Common follow-ups: Do you need to parse the body manually or does Next.js do it automatically?;How do you handle different HTTP methods like GET and POST in the same route?

Data Fetching;Form Handling & Validation in Next.js

How do you handle different HTTP methods such as GET, POST, and DELETE within a single API route file?

Intermediate
You check the req.method value at the top of your handler function and run different logic depending on whether the request is a GET, POST, or DELETE, returning an appropriate response or an error status for methods you do not support.
export default function handler(req, res) {
  if (req.method === 'POST') {
    return res.status(201).json({ created: true });
  }
  if (req.method === 'GET') {
    return res.status(200).json({ items: [] });
  }
  res.status(405).json({ error: 'Method not allowed' });
}
Real-world example A todo list API route supports GET to fetch tasks and POST to create new ones, all handled cleanly inside one file based on the incoming request method.

Common follow-ups: What status code should you return for unsupported methods?;How do you add authentication checks to an API route?

Route Handlers (API Route.js);Security Best Practices in Next.js

How can you protect an API route so that only authenticated users can access it?

Intermediate
You check for a valid session or authentication token at the start of your handler, usually by reading a cookie or an authorization header, and return a 401 unauthorized response immediately if the check fails, before running any of the protected logic.
export default function handler(req, res) {
  const token = req.cookies.session;
  if (!token) {
    return res.status(401).json({ error: 'Not authenticated' });
  }
  res.status(200).json({ secret: 'protected data' });
}
Real-world example An account settings API route checks for a valid session cookie before allowing a user to update their profile information, blocking anyone who is not properly signed in.

Common follow-ups: Should authentication checks be duplicated in every route or centralized somewhere?;How does this compare to using middleware for authentication?

Authentication & Authorization in Next.js;Cookies & Session Management in Next.js

What are common performance and security pitfalls to avoid when building API routes at scale?

Advanced
Common pitfalls include not validating incoming data which can lead to bad or malicious input, running slow database queries without caching, and not setting proper rate limits, which can let a single user overwhelm your server. Fixing these means validating input, caching where possible, and adding rate limiting for public endpoints.
import { z } from 'zod';

const schema = z.object({ email: z.string().email() });

export default function handler(req, res) {
  const result = schema.safeParse(req.body);
  if (!result.success) {
    return res.status(400).json({ error: 'Invalid input' });
  }
  res.status(200).json({ ok: true });
}
Real-world example A signup API route validates the submitted email format before creating an account, preventing malformed data from ever reaching the database and causing errors later.

Common follow-ups: What library is commonly used for validating request bodies in Next.js?;How would you add rate limiting to a public API route?

Security Best Practices in Next.js;Form Handling & Validation in Next.js