Data Validation with Zod
Zod is a TypeScript-first validation library.
Installation
bash
npm install zodBasic Schemas
typescript
import { z } from 'zod'; // Stringsconst nameSchema = z.string().min(2).max(100); // Numbersconst priceSchema = z.number().positive(); // Objectsconst productSchema = z.object({ name: z.string().min(2), price: z.number().positive(), description: z.string().optional(),}); // Inferring TypeScript typetype Product = z.infer<typeof productSchema>;Validation Middleware
typescript
// src/middlewares/validate.middleware.tsimport { Request, Response, NextFunction } from 'express';import { AnyZodObject, ZodError } from 'zod'; export const validate = (schema: AnyZodObject) => { return async (req: Request, res: Response, next: NextFunction) => { try { await schema.parseAsync({ body: req.body, query: req.query, params: req.params, }); next(); } catch (error) { if (error instanceof ZodError) { return res.status(400).json({ error: 'Validation error', details: error.errors.map(e => ({ field: e.path.join('.'), message: e.message, })), }); } next(error); } };};Validation Schemas
typescript
// src/schemas/product.schema.tsimport { z } from 'zod'; export const createProductSchema = z.object({ body: z.object({ name: z.string() .min(2, 'Name must have at least 2 characters') .max(200, 'Name too long'), price: z.number() .positive('Price must be positive'), description: z.string().optional(), categoryId: z.string().uuid('Invalid category'), }),}); export const updateProductSchema = z.object({ params: z.object({ id: z.string().uuid(), }), body: z.object({ name: z.string().min(2).max(200).optional(), price: z.number().positive().optional(), }),}); export type CreateProductInput = z.infer<typeof createProductSchema>['body'];Usage in Routes
typescript
import { validate } from '../middlewares/validate.middleware';import { createProductSchema, updateProductSchema } from '../schemas/product.schema'; router.post('/', validate(createProductSchema), controller.store); router.put('/:id', validate(updateProductSchema), controller.update);Common Validations
typescript
// Emailz.string().email() // URLz.string().url() // UUIDz.string().uuid() // Enumz.enum(['ADMIN', 'USER']) // Arraysz.array(z.string()).min(1) // Datesz.coerce.date() // Transformationsz.string().transform(val => val.toLowerCase())Summary
- ✅ Zod for declarative validation
- ✅ Automatic TypeScript type inference
- ✅ Reusable validation middleware
- ✅ Formatted error messages
Next lesson: Error Handling! 🚀