DevRocket
Security

Schema Validation

Validating the data of your API routes is a good practice to ensure the integrity and security of your application. This guide demonstrates how to use Zod, a powerful schema validation library, to validate the data in NestJS API routes.

Step 1: Install Zod

  1. Install Zod in your NestJS project:

    cd backend
    npm install zod
  2. Optionally, install Zod typings for TypeScript support:

    npm install --save-dev @types/zod

Step 2: Create a DTO for Validation

  1. Define a Schema: Create a schema for validation using Zod. For example:

    import { z } from 'zod';
     
    export const CreateUserSchema = z.object({
      email: z.string().email(),
    });
  2. Use the Schema in a DTO: Combine the schema with NestJS Data Transfer Object (DTO) patterns if needed:

    export class CreateUserDto {
      static schema = CreateUserSchema;
    }

Step 3: Validate Data in a Controller

  1. Update the Controller: Use the Zod schema to validate incoming data in your controller methods:
    import { Controller, Post, Body, BadRequestException } from '@nestjs/common';
    import { z } from 'zod';
    import { CreateUserSchema } from './schemas/create-user.schema';
     
    @Controller('user')
    export class UserController {
      @Post()
      async createUser(@Body() body: any) {
        const validationResult = CreateUserSchema.safeParse(body);
     
        if (!validationResult.success) {
          throw new BadRequestException('Invalid data: ' + validationResult.error.message);
        }
     
        return { email: validationResult.data.email };
      }
    }

The safeParse Method Explaination:

  • The safeParse method checks the data against the schema and returns:
    • success: true: If the data is valid.
    • success: false: If the data is invalid, along with the error details.

Step 4: Handle Validation Errors Globally (Optional)

  1. Create a Custom Pipe: Create a validation pipe to centralize schema validation:

    import { PipeTransform, Injectable, ArgumentMetadata, BadRequestException } from '@nestjs/common';
    import { z, ZodSchema } from 'zod';
     
    @Injectable()
    export class ZodValidationPipe implements PipeTransform {
      constructor(private schema: ZodSchema) {}
     
      transform(value: any, metadata: ArgumentMetadata) {
        const result = this.schema.safeParse(value);
        if (!result.success) {
          throw new BadRequestException('Validation failed: ' + result.error.message);
        }
        return result.data;
      }
    }
  2. Use the Pipe in a Controller: Apply the custom pipe directly to a controller method:

    @Controller('user')
    export class UserController {
      @Post()
      async createUser(
        @Body(new ZodValidationPipe(CreateUserSchema)) body: any,
      ) {
        return { email: body.email };
      }
    }

Step 5: Test Your API

  1. Start Your Application: Run the NestJS application:

    npm run start:dev
  2. Send Test Requests: Use Postman, cURL, or any HTTP client to test the API:

    curl -X POST http://localhost:3000/user -H "Content-Type: application/json" -d '{"email": "invalid-email"}'

    You should receive a 400 Bad Request response for invalid data.


Congratulations!

You’ve successfully implemented schema validation in NestJS using Zod. This approach ensures that your API routes are robust and secure by validating the incoming data. 🎉

On this page