Next.js API Routes Building Server-Side Functionality

Next.js API Routes enable the creation of standalone server-side functionality within a Next.js application, capable of handling HTTP requests and returning JSON data or other responses. API routes reside in the pages/api directory, with each file mapp…


This content originally appeared on DEV Community and was authored by Tianya School

Next.js API Routes enable the creation of standalone server-side functionality within a Next.js application, capable of handling HTTP requests and returning JSON data or other responses. API routes reside in the pages/api directory, with each file mapping to a specific API endpoint.

Basic Example

pages/api/users.js

import type { NextApiRequest, NextApiResponse } from 'next';

// Get user list
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
  if (req.method === 'GET') {
    const users = [
      { id: 1, name: 'User 1' },
      { id: 2, name: 'User 2' },
      { id: 3, name: 'User 3' },
    ];

    res.status(200).json(users);
  } else if (req.method === 'POST') {
    const user = req.body;

    // Simulate database connection
    // await addUserToDatabase(user);

    res.status(201).json({ message: 'User added successfully.' });
  } else {
    res.setHeader('Allow', ['GET', 'POST']);
    res.status(405).end(`Method ${req.method} Not Allowed`);
  }
}
  1. The pages/api/users.js file defines an API route accessible at /api/users.
  2. The handler function accepts two parameters: req (a NextApiRequest object representing the HTTP request) and res (a NextApiResponse object for the HTTP response).
  3. For GET requests, it returns a user list (hardcoded here, but typically queried from a database in practice).
  4. For POST requests, it accepts user data from the request body, simulates adding it to a database, and returns a success message.
  5. For unsupported methods, it returns a 405 Method Not Allowed error with allowed methods specified.

Next.js API Routes handle JSON responses by default, but you can return other content types as needed. For example, use res.send to return HTML.

Middleware and Request Handling Chain

Next.js API Routes support a middleware pattern, allowing preprocessing of requests or post-processing of responses before reaching the final handler. This is useful for validating headers, authentication, logging, etc.

Middleware Example

To validate an API key for all API requests:

// pages/api/middleware/authenticate.ts
export function authenticate(req: NextApiRequest, res: NextApiResponse, next: () => void) {
  const apiKey = req.headers['x-api-key'];

  if (!apiKey || apiKey !== process.env.API_KEY) {
    return res.status(401).json({ message: 'Unauthorized' });
  }

  next();
}

Apply the middleware in an API route:

// pages/api/users.js
import { authenticate } from './middleware/authenticate';

export default async function handler(req: NextApiRequest, res: NextApiResponse) {
  authenticate(req, res, () => {
    // Original logic
  });
}

Error Handling

Robust error handling is critical for production-grade applications. Next.js API Routes allow custom error handling logic.

Error Handling Example

export default async function handler(req: NextApiRequest, res: NextApiResponse) {
  try {
    // Code that might throw an error
    const result = await fetchDataFromDatabase();

    res.status(200).json(result);
  } catch (error) {
    console.error('Error occurred:', error);
    res.status(500).json({ error: 'An error occurred while processing your request.' });
  }
}

Type Safety

Using TypeScript for type annotations enhances code robustness and maintainability.

Type Safety Example

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

type User = {
  id: number;
  name: string;
};

export default async function handler(req: NextApiRequest, res: NextApiResponse<User[] | { message: string }>) {
  // ...
}

Interacting with External Services

Most API routes interact with external services like databases or third-party APIs. Here’s how to use axios for HTTP requests.

Install axios:

npm install axios

Use in an API route:

import axios from 'axios';

export default async function handler(req: NextApiRequest, res: NextApiResponse) {
  try {
    const response = await axios.get('https://api.example.com/data');
    res.status(200).json(response.data);
  } catch (error) {
    res.status(500).json({ error: 'Failed to fetch data from external service.' });
  }
}

Custom and Dynamic Routes

Next.js API Routes support more than single paths, allowing complex routing structures, including dynamic routes.

Custom Routes

To organize related API endpoints, use subdirectories. For a blog API, you might structure it as:

pages/
  api/
    blog/
      posts.ts          # Handles /api/blog/posts requests
      post/[id].ts      # Dynamic route, handles /api/blog/post/:id requests

Dynamic Routes

Dynamic routes capture URL segments as parameters. In the above example, [id] is a dynamic segment replaced by an actual ID. Access these parameters via req.query.

Dynamic Route Example (pages/api/blog/post/[id].ts)

export default async function handler(req: NextApiRequest, res: NextApiResponse) {
  const { id } = req.query; // Get dynamic ID

  if (!id) {
    return res.status(400).json({ message: 'Missing post ID' });
  }

  try {
    const post = await getPostById(id as string); // Assume this fetches a post from a database
    if (!post) {
      return res.status(404).json({ message: 'Post not found' });
    }
    return res.status(200).json(post);
  } catch (error) {
    console.error('Error fetching post:', error);
    return res.status(500).json({ message: 'Internal server error' });
  }
}

API Route Caching

To improve performance, you may want to cache API responses. Next.js doesn’t provide built-in API caching, but you can use client-side libraries like swr or server-side caching with services like Redis.

Server-Side Caching Example (Using Redis)

Install redis and ioredis:

npm install redis ioredis

Use Redis to cache data in an API route:

import redis from 'ioredis';

const redisClient = new redis(process.env.REDIS_URL);

export default async function handler(req: NextApiRequest, res: NextApiResponse) {
  const { id } = req.query;

  let post;
  try {
    // Try fetching from Redis cache
    post = await redisClient.get(`post:${id}`);
    if (post) {
      post = JSON.parse(post);
      return res.status(200).json(post);
    }
  } catch (err) {
    console.error('Redis error:', err);
  }

  // Fetch from database if not cached
  post = await getPostById(id as string);

  if (post) {
    // Store in Redis for future requests
    redisClient.set(`post:${id}`, JSON.stringify(post));
    res.status(200).json(post);
  } else {
    res.status(404).json({ message: 'Post not found' });
  }
}

CORS Support

Cross-Origin Resource Sharing (CORS) is a key aspect of web security. Next.js API Routes support CORS by default, but you can further control CORS policies.

CORS Example

import Cors from 'cors'; // Install cors library

// Initialize CORS middleware
const cors = Cors({
  methods: ['GET', 'HEAD'],
});

export default async function handler(req: NextApiRequest, res: NextApiResponse) {
  // Apply CORS middleware
  await new Promise((resolve, reject) => {
    cors(req, res, (result) => {
      if (result instanceof Error) {
        reject(result);
      } else {
        resolve(result);
      }
    });
  });

  // Subsequent handling logic
}

🎁 I have compiled a complete series of advanced programming collections on Patreon:

  • Weekly updated technical tutorials and project practice
  • High-quality programming course PDF downloads
  • Front-end / Back-end / Full Stack / Architecture Learning Collection
  • Subscriber Exclusive Communication Group

👉 Click to join and systematically improve development capabilities: Advanced Development Tutorial


This content originally appeared on DEV Community and was authored by Tianya School


Print Share Comment Cite Upload Translate Updates
APA

Tianya School | Sciencx (2025-07-12T06:41:29+00:00) Next.js API Routes Building Server-Side Functionality. Retrieved from https://www.scien.cx/2025/07/12/next-js-api-routes-building-server-side-functionality/

MLA
" » Next.js API Routes Building Server-Side Functionality." Tianya School | Sciencx - Saturday July 12, 2025, https://www.scien.cx/2025/07/12/next-js-api-routes-building-server-side-functionality/
HARVARD
Tianya School | Sciencx Saturday July 12, 2025 » Next.js API Routes Building Server-Side Functionality., viewed ,<https://www.scien.cx/2025/07/12/next-js-api-routes-building-server-side-functionality/>
VANCOUVER
Tianya School | Sciencx - » Next.js API Routes Building Server-Side Functionality. [Internet]. [Accessed ]. Available from: https://www.scien.cx/2025/07/12/next-js-api-routes-building-server-side-functionality/
CHICAGO
" » Next.js API Routes Building Server-Side Functionality." Tianya School | Sciencx - Accessed . https://www.scien.cx/2025/07/12/next-js-api-routes-building-server-side-functionality/
IEEE
" » Next.js API Routes Building Server-Side Functionality." Tianya School | Sciencx [Online]. Available: https://www.scien.cx/2025/07/12/next-js-api-routes-building-server-side-functionality/. [Accessed: ]
rf:citation
» Next.js API Routes Building Server-Side Functionality | Tianya School | Sciencx | https://www.scien.cx/2025/07/12/next-js-api-routes-building-server-side-functionality/ |

Please log in to upload a file.




There are no updates yet.
Click the Upload button above to add an update.

You must be logged in to translate posts. Please log in or register.