Validation (Zod)

Nova uses Zod for both request body validation and response validation. Validation errors are automatically returned as structured error responses.

Request Body Validation

Use the @Body decorator with a Zod schema to validate incoming request bodies:

dto/create-user.ts TypeScript
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'),
  age: z.number().int().min(0).optional(),
  role: z.enum(['admin', 'user', 'moderator']).default('user'),
});

export type CreateUserDto = z.infer<typeof CreateUserSchema>;
user.controller.ts TypeScript
import { Controller, Post, Body } from '@abrahambass/nova';
import { CreateUserSchema, type CreateUserDto } from './dto/create-user';

@Controller('/users')
class UserController {
  @Post()
  async create(@Body(CreateUserSchema) data: CreateUserDto) {
    // data is fully validated and typed
    return { id: 1, ...data };
  }
}

Validation Error Response

When validation fails, Nova returns a structured error response:

Response (404) json
{
  "detail": [
    {
      "loc": ["body", "email"],
      "msg": "Invalid email address",
      "type": "invalid"
    },
    {
      "loc": ["body", "name"],
      "msg": "Name must be at least 2 characters",
      "type": "invalid"
    }
  ]
}

Response Validation

You can also validate the response using the responseModel option in your route decorator:

Example TypeScript
const UserResponseSchema = z.object({
  id: z.number(),
  name: z.string(),
  email: z.string(),
});

@Get('/:id', {
  responseModel: UserResponseSchema,
  includeInSchema: true,
})
async findById(@Path('id') id: number) {
  // If the return value doesn't match the schema,
  // a ResponseValidationError (500) is thrown
  return this.userService.findById(id);
}
💡 Tip

Response validation is great for catching bugs in development. If the response doesn't match the schema, a 500 Internal Server Error is thrown so you can catch data shape issues early.

Path & Query Parameter Validation

Path and query parameters are automatically type-cast based on their TypeScript types:

TypeScript TypeCasting BehaviorError on Invalid
stringConverted to stringNo
numberParsed as numberYes — InvalidParamTypeError
booleanAccepts "true"/"false"Yes — InvalidParamTypeError
DateParsed as DateYes — InvalidParamTypeError