Protect NextJS API with Zod


A basic step for securing our APIs is to validate the data that we receive. Various libraries can help us with this task, and in this post, we will demonstrate how to use Zod to validate data in your NextJS API routes.

What is Zod?

Zod is a TypeScript library for data validation. It’s a great tool for validating data in your NextJS API routes as it allows you to create specific schemas to validate the data you receive.

Install Zod

To install Zod, run the following command:

npm install zod

Usage

Zod provides a set of functions to create schemas, these schemas can be used to validate data.

Create a schema

To create a schema, we can use the z.object function, this function receives an object with the properties that we want to validate.

import { z } from "zod";

const schema = z.object({
  name: z.string(),
  age: z.number(),
});

Validate data

To validate data, we can use the parse function, this function receives the data that we want to validate and returns the validated data.

const data = {
  name: "John",
  age: 30,
};

const validatedData = schema.parse(data);

Validate data with a custom error message

To validate data with a custom error message, we can use the parseAsync function, this function receives the data that we want to validate and returns a promise with the validated data.

const data = {
  name: "John",
  age: "30",
};

const validatedData = await schema.parseAsync(data).catch((error) => {
  throw new Error("Invalid data");
});

Using Zod with Next.JS API routes

In this example, we will create a NextJS API route to create a user, we will use Zod to validate the data that we receive.

Create a NextJS API route

To create a NextJS API route, we can create a file in the pages/api directory, this file will be an API route.

// pages/api/users/create.ts
import { NextApiRequest, NextApiResponse } from "next";

export default (req: NextApiRequest, res: NextApiResponse) => {
  const data = req.body;
  res.status(200).json({ message: `Hello ${data.name}!` });
};

Validate data

To validate data, we can use the parse function, this function receives the data that we want to validate and returns the validated data.

// pages/api/users/create.ts
import { NextApiRequest, NextApiResponse } from "next";
import { z } from "zod";

export default (req: NextApiRequest, res: NextApiResponse) => {
  const schema = z.object({
    name: z.string(),
  });

  const validatedData = schema.parse(req.body);

  res.status(200).json({ message: `Hello ${validatedData.name}!` });
};

Validate data with a custom error message

To validate data with a custom error message, we can use the parseAsync function, this function receives the data that we want to validate and returns a promise with the validated data.

// pages/api/users/create.ts
import { NextApiRequest, NextApiResponse } from "next";
import { z } from "zod";

export default async (req: NextApiRequest, res: NextApiResponse) => {
  const schema = z.object({
    name: z.string(),
  });

  const validatedData = await schema.parseAsync(req.body).catch((error) => {
    return res.status(200).json({ message: `Invalid data`, error });
  });

  res.status(200).json({ message: `Hello ${validatedData.name}!` });
};

Validate data using parseSafe

To validate data using parseSafe, we can use the parseSafe function, this function receives the data that we want to validate and returns an object with the validated data and the error.

// pages/api/users/create.ts
import { NextApiRequest, NextApiResponse } from "next";
import { z } from "zod";

export default (req: NextApiRequest, res: NextApiResponse) => {
  const schema = z.object({
    name: z.string(),
  });

  const response = schema.safeParse(req.body);

  if (!response.success) {
    return res.status(400).send({
      message: `Yo, bad payload!`,
      error: response.error,
    });
  }

  res.status(200).json({ message: `Hello ${response.data.name}!` });
};

Final Words

In this post, we saw how to use Zod to validate data in our NextJS API routes, Zod is a great tool to validate data in our NextJS API routes. If you want to learn more about Zod, you can check the Zod documentation.