Documentation Index Fetch the complete documentation index at: https://mintlify.com/LizandroCanul/back_sdo/llms.txt
Use this file to discover all available pages before exploring further.
Overview
The API uses class-validator and class-transformer to automatically validate incoming requests through DTOs (Data Transfer Objects). Validation is configured globally in main.ts.
Global Validation Configuration
Validation is enabled application-wide with these settings:
import { ValidationPipe } from '@nestjs/common' ;
app . useGlobalPipes (
new ValidationPipe ({
whitelist: true , // Removes unknown properties
forbidNonWhitelisted: true , // Throws error for unknown properties
transform: true , // Auto-converts types (crucial for nested DTOs)
}),
);
The transform: true option is critical for nested DTOs and type conversions. It automatically converts plain JSON objects to DTO class instances.
Configuration Options Explained
Automatically strips properties that don’t have validation decorators. Example: // Request body
{
"nombre" : "Test" ,
"hackerField" : "malicious" // This will be removed
}
forbidNonWhitelisted: true
Instead of silently removing unknown properties, it throws a 400 Bad Request error. Response: {
"statusCode" : 400 ,
"message" : [ "property hackerField should not exist" ],
"error" : "Bad Request"
}
Common Validation Decorators
String Validation
Basic String
Email
With Transform
@ IsString ()
@ IsNotEmpty ()
@ MaxLength ( 255 )
nombre : string ;
Number Validation
@ IsNumber ()
@ IsNotEmpty ()
municipioId : number ;
Optional Fields
Optional String
Optional with Default
@ IsString ()
@ IsOptional ()
descripcion ?: string ;
Enum Validation
export enum TipoGeometria {
PUNTO = 'PUNTO' ,
RUTA = 'RUTA' ,
POLIGONO = 'POLIGONO' ,
}
@ IsEnum ( TipoGeometria )
@ IsOptional ()
tipoGeometria ?: TipoGeometria ;
Boolean Validation
@ IsBoolean ()
@ IsOptional ()
activo ?: boolean ;
Nested DTO Validation
For complex objects with nested DTOs, use @ValidateNested() with @Type():
create-obra.dto.ts
create-obra-ubicacion.dto.ts
import { Type } from 'class-transformer' ;
import { IsArray , ValidateNested , IsOptional } from 'class-validator' ;
import { CreateObraUbicacionDto } from './create-obra-ubicacion.dto' ;
export class CreateObraDto {
@ IsString ()
@ IsNotEmpty ()
nombre : string ;
// Nested array of location DTOs
@ IsArray ()
@ ValidateNested ({ each: true }) // Validates each item in array
@ Type (() => CreateObraUbicacionDto ) // Transforms to DTO instances
@ IsOptional ()
ubicaciones ?: CreateObraUbicacionDto [];
}
Without @Type() decorator, nested DTOs won’t be validated. The transform: true option in ValidationPipe requires this decorator to work with nested objects.
Real-World DTO Examples
CreateUserDto
import { IsEmail , IsString , MinLength , IsOptional , IsIn , IsBoolean } from 'class-validator' ;
export class CreateUserDto {
@ IsString ()
@ MinLength ( 3 )
nombreCompleto : string ;
@ IsString ()
@ IsEmail ()
email : string ;
@ IsString ()
@ MinLength ( 6 , { message: 'La contraseña debe tener al menos 6 caracteres' })
password : string ;
@ IsOptional ()
@ IsString ()
@ IsIn ([ 'admin' , 'user' ])
roles ?: string ;
@ IsOptional ()
@ IsBoolean ()
isActive ?: boolean ;
}
Location: /home/daytona/workspace/source/src/users/dto/create-user.dto.ts:1
CreateMunicipioDto
import { IsString , IsNotEmpty , IsNumber , Min , Max , IsOptional , IsBoolean } from 'class-validator' ;
import { Transform } from 'class-transformer' ;
export class CreateMunicipioDto {
@ IsString ()
@ IsNotEmpty ()
@ Transform (({ value }) => value ?. trim ())
nombre : string ;
@ IsNumber ()
@ IsNotEmpty ()
@ Min ( - 90 )
@ Max ( 90 )
latitud : number ;
@ IsNumber ()
@ IsNotEmpty ()
@ Min ( - 180 )
@ Max ( 180 )
longitud : number ;
@ IsBoolean ()
@ IsOptional ()
activo ?: boolean ;
}
Location: /home/daytona/workspace/source/src/municipios/dto/create-municipio.dto.ts:1
CreateObraDto (Complex)
import { IsString , IsNotEmpty , IsArray , ValidateNested , IsNumber , IsOptional , IsPositive , Min , MaxLength } from 'class-validator' ;
import { Type } from 'class-transformer' ;
import { CreateObraUbicacionDto } from './create-obra-ubicacion.dto' ;
export class CreateObraDto {
// Fiscal year
@ IsNumber ()
@ IsNotEmpty ()
ejercicioFiscalId : number ;
// Unique key
@ IsString ()
@ IsNotEmpty ()
@ MaxLength ( 50 )
claveUnica : string ;
// Name
@ IsString ()
@ IsNotEmpty ()
@ MaxLength ( 255 )
nombre : string ;
// Description
@ IsString ()
@ IsOptional ()
descripcion ?: string ;
// Department
@ IsNumber ()
@ IsNotEmpty ()
dependenciaId : number ;
// Budget
@ IsNumber ({ maxDecimalPlaces: 2 })
@ IsPositive ()
@ Min ( 0 )
monto : number ;
// Municipality
@ IsNumber ()
@ IsNotEmpty ()
municipioId : number ;
// Project type (optional)
@ IsNumber ()
@ IsOptional ()
tipoProyectoId ?: number ;
// Status
@ IsNumber ()
@ IsNotEmpty ()
estatusObraId : number ;
// Nested locations array
@ IsArray ()
@ ValidateNested ({ each: true })
@ Type (() => CreateObraUbicacionDto )
@ IsOptional ()
ubicaciones ?: CreateObraUbicacionDto [];
}
Location: /home/daytona/workspace/source/src/obras/dto/create-obra.dto.ts:1
Validation Error Responses
When validation fails, NestJS returns a standardized error response:
Single Error
Multiple Errors
Nested Validation Error
{
"statusCode" : 400 ,
"message" : [
"email must be an email"
],
"error" : "Bad Request"
}
Custom Validation Messages
You can customize error messages using the decorator options:
Custom Message
Multiple Constraints
@ MinLength ( 6 , { message: 'La contraseña debe tener al menos 6 caracteres' })
password : string ;
Best Practices
Always Use DTOs Never accept raw request bodies. Create a DTO for every endpoint that accepts data.
Be Explicit Use @IsNotEmpty() for required fields and @IsOptional() for optional ones.
Type Safety Combine validation with TypeScript types for compile-time and runtime safety.
Nested Validation Don’t forget @Type() and @ValidateNested() for nested objects and arrays.
The transform: true configuration (set in main.ts:13) is essential for:
Auto-converting query parameters from strings
Transforming nested DTOs
Type coercion (string to number, etc.)
Common Validation Patterns
Password Validation
@ IsString ()
@ MinLength ( 6 , { message: 'La contraseña debe tener al menos 6 caracteres' })
password : string ;
Geographic Coordinates
@ IsNumber ()
@ Min ( - 90 )
@ Max ( 90 )
latitud : number ;
@ IsNumber ()
@ Min ( - 180 )
@ Max ( 180 )
longitud : number ;
Money/Currency
@ IsNumber ({ maxDecimalPlaces: 2 })
@ IsPositive ()
@ Min ( 0 )
monto : number ;
Trimmed Strings
@ IsString ()
@ IsNotEmpty ()
@ Transform (({ value }) => value ?. trim ())
nombre : string ;
Next Steps
Database Schema Learn about entity relationships
Error Handling Understand error responses