Zod: A Data Validation Library
Introduction to Zod
Zod is a powerful library for data validation in JavaScript and TypeScript. It helps ensure that your data meets certain criteria, making your applications more robust and error-free.
Why Use Zod?
Type Safety: Ensures that data conforms to specific types.
Validation: Checks that data meets certain rules (e.g., an email must be in a valid email format).
Error Handling: Provides detailed error messages.
Flexibility: Can be used in various scenarios like form validation, API response validation, etc.
Installation
First, let's install Zod using npm or yarn.
npm install zod
or
yarn add zod
Basic Usage
Let's start with a simple example. Suppose we want to validate user data that includes a name, age, and email.
Import Zod:
const { z } = require('zod');
Define a Schema:
A schema is a blueprint that defines the structure and validation rules for your data.
const userSchema = z.object({ name: z.string().min(1, 'Name is required'), age: z.number().int().positive('Age must be a positive integer'), email: z.string().email('Invalid email address'), });
Validate Data:
Use the schema to validate data.
const result = userSchema.safeParse({ name: "John Doe", age: 30, email: "john.doe@example.com", }); if (result.success) { console.log('Data is valid:', result.data); } else { console.error('Validation errors:', result.error.errors); }
Using Zod with Express
Zod can be very useful in validating request data in an Express application. Let’s see how to do this.
Setup Express:
const express = require('express'); const { z } = require('zod'); const app = express(); app.use(express.json());
Define a Schema:
We’ll use the same user schema from above.
Validate Request Data:
app.post('/users', (req, res) => { const result = userSchema.safeParse(req.body); if (!result.success) { return res.status(400).json({ errors: result.error.errors }); } res.status(201).json(result.data); }); app.listen(3000, () => { console.log('Server is running on port 3000'); });
Advanced Features
Nested Objects
Zod can handle complex nested structures.
const addressSchema = z.object({
street: z.string(),
city: z.string(),
postalCode: z.string().regex(/^\d{5}(-\d{4})?$/, 'Invalid postal code'),
});
const userSchema = z.object({
name: z.string(),
age: z.number().int().positive(),
email: z.string().email(),
address: addressSchema,
});
Arrays and Tuples
const stringArraySchema = z.array(z.string());
const tupleSchema = z.tuple([z.string(), z.number(), z.boolean()]);
Unions and Enums
const statusSchema = z.union([z.literal('success'), z.literal('error')]);
const exampleUnion = z.union([z.string(), z.number()]);
const roleSchema = z.enum(['admin', 'user', 'guest']);
Custom Validation
You can add custom validation logic.
const passwordSchema = z.string().min(8).max(20).refine((val) => /[A-Z]/.test(val), {
message: "Password must contain at least one uppercase letter",
});
Using Middleware for Validation
To keep our code clean, we can use middleware for validation.
Create Middleware:
const validateSchema = (schema) => (req, res, next) => { const result = schema.safeParse(req.body); if (!result.success) { return res.status(400).json({ errors: result.error.errors }); } req.validatedBody = result.data; next(); };
Apply Middleware:
app.post('/users', validateSchema(userSchema), (req, res) => { res.status(201).json(req.validatedBody); });
Summary
Installation: Install Zod using npm or yarn.
Schema Definition: Define schemas to specify the structure and validation rules of your data.
Validation: Use schemas to validate data and handle errors.
Integration with Express: Validate request data in Express applications.
Advanced Features: Handle nested objects, arrays, tuples, unions, enums, and custom validation logic.
Middleware: Use middleware for clean and reusable validation logic.
Practice Exercises
Simple Validation: Create a schema to validate a product object with
name
,price
, andcategory
.API Validation: Create an Express route to validate and handle a POST request for creating a new product.
Advanced Schema: Create a schema for a blog post that includes a
title
,content
,author
, and an array oftags
.
Subscribe to my newsletter
Read articles from Muhammad Kamil Raza directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by