John Polacek

Chicago Web Developer

Engineering manager and frontend lead at Howl

My product recommendations at shop.howl.me

Shipping open source on Github

Follow me at @johnpolacek

Next.js API Route Handler Utility Function

Originally published on 4/21/2023
Handle API Request Code Example

TLDR; - get the utility from this gist.

Next.js provides a built-in API routes feature that allows you to easily create serverless API endpoints. It makes handling API requests with different HTTP methods and error handling straightforward. In this blog post, we'll create a reusable utility function called handleApiRequest to further simplify and standardize our API route handlers.

Getting Started

Let's say you've already set up a Next.js project and you're ready to create API route handlers. We'll create a utility function handleApiRequest that simplifies the process of handling different request methods, executing the actual request logic, and handling errors.

Creating the handleApiRequest Utility

First, create a utils folder in your project's root directory and add a new file called api-utils.ts. Inside this file, we'll create the handleApiRequest function along with an error handling utility called handleErrorResponse.

// utils/api-utils.ts
import { NextApiRequest, NextApiResponse } from "next";
export async function handleApiRequest(
req: NextApiRequest,
res: NextApiResponse,
expectedReqMethod: string,
handleRequest: (body: any) => Promise<any>
): Promise<void> {
if (req.method === expectedReqMethod) {
try {
const responseData = await handleRequest(req.body);
res.status(200).json(responseData);
} catch (error: unknown) {
handleErrorResponse(res, error);
}
} else {
res.status(405).json({ error: "Method not allowed" });
}
}
export function handleErrorResponse(
res: NextApiResponse,
error: unknown
): void {
if (error instanceof Error) {
res.status(500).json({ error: error.message });
} else {
res.status(500).json({ error: "An unknown error occurred" });
}
}

How Does It Work?

The handleApiRequest function accepts four parameters:

  • req: The NextApiRequest object.
  • res: The NextApiResponse object.
  • expectedReqMethod: The expected HTTP method for the API route handler (e.g., "GET", "POST", "PUT", etc.).
  • handleRequest: A function that handles the actual request logic and returns a promise.

It checks if the request method matches the expected method. If it does, it executes the handleRequest function and sends the response. If an error occurs, it calls handleErrorResponse to handle the error and send the appropriate response. If the request method does not match the expected method, it returns a 405 status code with a "Method not allowed" error message.

Using the handleApiRequest Utility

Here’s example with a simple API route handler that accepts user messages and stores them in an array. The API route will have two endpoints: one for creating messages (POST) and another for fetching messages (GET).

First, create a file called messages.ts in the pages/api folder. We'll use the handleApiRequest utility to handle both GET and POST requests.

// pages/api/messages.ts
import { NextApiRequest, NextApiResponse } from "next";
import { handleApiRequest } from "@/utils/api-utils";
// This array will store messages for demonstration purposes.
// In a real application, you should store messages in a database.
const messages: string[] = [];
async function handleGetMessages() {
return { messages };
}
async function handleCreateMessage(body: any) {
const { message } = body;
if (!message || typeof message !== "string") {
throw new Error("Invalid message");
}
messages.push(message);
return { success: true };
}
export default async function handler(
req: NextApiRequest,
res: NextApiResponse
) {
if (req.method === "GET") {
await handleApiRequest(req, res, "GET", handleGetMessages);
} else if (req.method === "POST") {
await handleApiRequest(req, res, "POST", handleCreateMessage);
} else {
res.status(405).json({ error: "Method not allowed" });
}
}

Now, when a GET request is sent to /api/messages, the API will return the array of messages. When a POST request is sent to /api/messages with a message in the request body, it will add the message to the array and return a success status.

The handleApiRequest utility simplifies the process of handling different request methods and errors by wrapping the actual request logic in a standardized way.