### Validation
Validate every piece of data a web application receives before acting on it. Nest provides several pipes that validate incoming requests automatically:
- `ValidationPipe` validates classes decorated with [class-validator](https://github.com/typestack/class-validator) rules.
- `StandardSchemaValidationPipe` validates schemas written with [Zod](https://zod.dev/), [Valibot](https://valibot.dev/), [ArkType](https://arktype.io/), or any other [Standard Schema](https://standardschema.dev/) compatible library.
- `ParseIntPipe`, `ParseBoolPipe`, `ParseArrayPipe`, and `ParseUUIDPipe` validate and convert individual values.
#### Overview
The [Pipes](/pipes) chapter explains how pipes work and how to bind them to parameters, route handlers, controllers, or the whole application. This chapter builds on it and covers real-world use of the two validation pipes.
The pipes differ in where the validation rules live:
- With `ValidationPipe`, rules are decorators on a **DTO class**, and the class is also the parameter's TypeScript type. This approach integrates with the [mapped types](#mapped-types) utilities and with the Swagger CLI plugin.
- With `StandardSchemaValidationPipe`, rules are a **schema object**, and the parameter's TypeScript type is inferred from the schema. Schemas compose with the methods of their library, and no class or reflection metadata is involved.
Both pipes can be registered at the same time. `ValidationPipe` only validates parameters typed with a class, and `StandardSchemaValidationPipe` only validates parameters that declare a schema, so you can adopt schemas incrementally in an existing application.
#### Using the built-in ValidationPipe
To begin using it, first install the required dependencies.
```bash
$ npm i --save class-validator class-transformer
```
> info **Hint** The `ValidationPipe` is exported from the `@nestjs/common` package.
Because this pipe uses the [`class-validator`](https://github.com/typestack/class-validator) and [`class-transformer`](https://github.com/typestack/class-transformer) libraries, it supports many options. Pass them in a configuration object to the pipe's constructor. The pipe's own options are:
```typescript
export interface ValidationPipeOptions extends ValidatorOptions {
transform?: boolean;
disableErrorMessages?: boolean;
exceptionFactory?: (errors: ValidationError[]) => any;
errorFormat?: 'list' | 'grouped';
}
```
In addition to these, all `class-validator` options (inherited from the `ValidatorOptions` interface) are available:
| Option |
Type |
Description |
enableDebugMessages |
boolean |
If set to true, validator will print extra warning messages to the console when something is not right. |
skipUndefinedProperties |
boolean |
If set to true then validator will skip validation of all properties that are undefined in the validating object. |
skipNullProperties |
boolean |
If set to true then validator will skip validation of all properties that are null in the validating object. |
skipMissingProperties |
boolean |
If set to true then validator will skip validation of all properties that are null or undefined in the validating object. |
whitelist |
boolean |
If set to true, validator will strip validated (returned) object of any properties that do not use any validation decorators. |
forbidNonWhitelisted |
boolean |
If set to true, instead of stripping non-whitelisted properties validator will throw an exception. |
forbidUnknownValues |
boolean |
If set to true, attempts to validate unknown objects fail immediately. |
disableErrorMessages |
boolean |
If set to true, validation errors will not be returned to the client. |
errorHttpStatusCode |
number |
This setting allows you to specify which exception type will be used in case of an error. By default it throws BadRequestException. |
exceptionFactory |
Function |
Takes an array of the validation errors and returns an exception object to be thrown. |
groups |
string[] |
Groups to be used during validation of the object. |
always |
boolean |
Set default for always option of decorators. Default can be overridden in decorator options. |
strictGroups |
boolean |
If groups is not given or is empty, ignore decorators with at least one group. |
dismissDefaultMessages |
boolean |
If set to true, the validation will not use default messages. Error message always will be undefined if
its not explicitly set. |
validationError.target |
boolean |
Indicates if target should be exposed in ValidationError. |
validationError.value |
boolean |
Indicates if validated value should be exposed in ValidationError. |
stopAtFirstError |
boolean |
When set to true, validation of the given property will stop after encountering the first error. Defaults to false. |
errorFormat |
'list' | 'grouped' |
Specifies the format of validation error messages. 'list' (default) returns an array of error message strings. 'grouped' returns an object with property paths as keys and arrays of unmodified error messages as values, preserving custom validation messages without prepending parent path prefixes. |
> info **Notice** Find more information about the `class-validator` package in its [repository](https://github.com/typestack/class-validator).
#### Auto-validation
Start by binding `ValidationPipe` at the application level, so that every endpoint is protected from receiving invalid data.
```typescript
async function bootstrap() {
const app = await NestFactory.create(AppModule);
app.useGlobalPipes(new ValidationPipe());
await app.listen(process.env.PORT ?? 3000);
}
await bootstrap();
```
To test the pipe, create a basic endpoint:
```typescript
@Post()
create(@Body() createUserDto: CreateUserDto) {
return 'This action adds a new user';
}
```
> info **Hint** TypeScript does not emit metadata for **generics or interfaces**, so `ValidationPipe` cannot validate DTOs declared with them. Use concrete classes for your DTOs.
> info **Hint** Don't import DTOs with a type-only import, because type-only imports are erased at runtime. Write `import {{ '{' }} CreateUserDto {{ '}' }}` instead of `import type {{ '{' }} CreateUserDto {{ '}' }}`.
Next, add validation rules to the `CreateUserDto` with the decorators provided by the `class-validator` package (see the [full list](https://github.com/typestack/class-validator#validation-decorators)). Every route that uses `CreateUserDto` then enforces these rules.
```typescript
import { IsEmail, IsNotEmpty } from 'class-validator';
export class CreateUserDto {
@IsEmail()
email: string;
@IsNotEmpty()
password: string;
}
```
With these rules in place, a request whose body contains an invalid `email` property receives a `400 Bad Request` response with the following body:
```json
{
"statusCode": 400,
"error": "Bad Request",
"message": ["email must be an email"]
}
```
`ValidationPipe` validates other parts of the request as well. For example, to accept only numeric values for the `:id` path parameter, use the following construct:
```typescript
@Get(':id')
findOne(@Param() params: FindOneParams) {
return 'This action returns a user';
}
```
Like a DTO, `FindOneParams` is a class that defines validation rules with `class-validator`:
```typescript
import { IsNumberString } from 'class-validator';
export class FindOneParams {
@IsNumberString()
id: string;
}
```
#### Disable detailed errors
Error messages explain what was wrong with a request, but some production environments prefer not to expose them. To disable detailed errors, pass an options object to the `ValidationPipe`:
```typescript
app.useGlobalPipes(
new ValidationPipe({
disableErrorMessages: true,
}),
);
```
As a result, the response body no longer contains detailed error messages.
#### Stripping properties
`ValidationPipe` can also filter out properties that the route handler should not receive. When you **whitelist** the acceptable properties, any property not included in the whitelist is stripped from the resulting object. For example, if the handler expects `email` and `password`, but a request also includes an `age` property, `age` is removed from the resulting DTO. To enable this behavior, set `whitelist` to `true`.
```typescript
app.useGlobalPipes(
new ValidationPipe({
whitelist: true,
}),
);
```
With this option enabled, properties without any decorator in the validation class are removed.
Alternatively, you can reject requests that contain non-whitelisted properties with an error response. To do so, set `forbidNonWhitelisted` to `true` in addition to `whitelist`.