Request Validator (Zod)

The Request Validator component provides a standardized way to validate request data (body, query parameters, and route parameters) in Servercn using Zod schemas.

It automatically:

  • Validates request body, query, and params using Zod schemas
  • Returns detailed validation error messages
  • Integrates seamlessly with Servercn error handling
  • Provides type-safe request data after validation

This middleware is designed for type-safe, schema-based validation in REST APIs.

Installation Guide

npx servercn-cli add request-validator

How Validation Works

The Request Validator middleware follows this sequence:

  1. Schema Definition: Define Zod schemas for body, query, or params
  2. Middleware Application: Apply validateRequest middleware to routes
  3. Validation: Middleware validates incoming request data against schemas
  4. Error Handling: If validation fails, returns detailed error messages
  5. Type Safety: Validated data is typed and attached to the request object

This ensures type-safe request handling with clear validation error messages.

Middleware Implementation

MVC: src/middlewares/validate-request.ts

Feature: src/shared/middlewares/validate-request.ts

import { Request, Response, NextFunction } from "express";
import z, { ZodError, type ZodObject } from "zod";
 
import { ApiError } from "../utils/api-error";
 
export const validateRequest = (schema: ZodObject<any>) => {
  return (req: Request, res: Response, next: NextFunction) => {
    try {
      schema.parse(req.body);
 
      next();
    } catch (error) {
      if (!(error instanceof ZodError)) {
        return next(error);
      }
 
      throw ApiError.badRequest(
        "Invalid request data",
        z.flattenError(error).fieldErrors || z.flattenError(error)
      );
    }
  };
};

Schema Definition

Create validation schemas using Zod.

MVC: src/validations/user.validation.ts

Feature: src/modules/user/user.validation.ts

import z from "zod";
 
export const createUserSchema = z.object({
  name: z.string().min(2, "Name must be at least 2 characters"),
  email: z.string().email("Invalid email address"),
  password: z.string().min(8, "Password must be at least 8 characters"),
  age: z.number().int().min(18).max(100).optional()
});

Usage Example

Apply the validateRequest middleware to your routes with the appropriate schema.

src/routes/user.routes.ts
import { Router } from "express";
import { validateRequest } from "../middlewares/validate-request";
import { createUserSchema } from "./user.validation";
 
const router = Router();
 
router.post("/", validateRequest(createUserSchema), (req, res) => {
  return res.status(201).json({ success: true, data: req.body });
});
 
export default router;

Validation Error Responses

When validation fails, the handler returns a standardized 400 Bad Request response with detailed error information:

{
  "success": false,
  "message": "Invalid request data",
  "statusCode": 400,
  "errors": {
    "email": ["Invalid email address"],
    "password": ["Password must be at least 8 characters"],
    "age": ["You must be 18 or older to create an account"]
  }
}

(The exact structure depends on your ApiError implementation.)

Best Practices

  • Separate Schemas: Create separate validation files for each resource/module
  • Reusable Schemas: Extract common validation patterns into shared schemas
  • Clear Error Messages: Provide descriptive error messages in your Zod schemas
  • Type Safety: Use Zod's type inference for TypeScript type safety
  • Transform Data: Use Zod's transform methods to convert query strings to numbers, dates, etc.
  • Validate Early: Apply validation middleware before business logic
  • Consistent Structure: Keep validation schemas organized and consistent across your application

File & Folder Structure

Loading files...

Installation

npx servercn-cli add request-validator