# Class Validator & Validation Pipe

## Introduction

* We can add a few decorators to the `dto` class to validate the body and query by using `class-validator` & `class-transformer` library

```typescript
import {
  IsArray,
  IsBoolean,
  IsNotEmpty,
  IsNumber,
  IsString,
  ValidateNested,
  IsObject,
} from 'class-validator';

import { Transform, Type } from 'class-transformer';

export class TestItem {
  @IsString()
  name: string;
}

export class WhereDto {
  @IsString()
  name: string;
  @IsBoolean()
  @Transform((value) => value.value === 'test')
  isTest: boolean;
  @IsArray()
  @ValidateNested({ each: true })
  @Type(() => TestItem)
  arr: TestItem[];
  @IsObject()
  @ValidateNested()
  @Type(() => TestItem)
  obj: TestItem;
}
```

```typescript
@Get('/test')
  async test(@Body() where: WhereDto) {
    console.log('where', where);
    return where;
  }
```

* The request body suppose should be&#x20;

```json
{
    "name": "test1",
    "isTest": 123,
    "obj": {"name": "test1"},
    "arr": [{"name":"test1"}]
}
```

* The output will be

```json
{
    "name": "test1",
    "isTest": false,
    "obj": {
        "name": "test1"
    },
    "arr": [
        {
            "name": "test1"
        }
    ]
}
```

## Validation pipe

*   It is best practice to validate the correctness of any data sent into a web application. To automatically validate incoming requests, Nest provides several pipes available right out-of-the-box:

    * `ValidationPipe`
    * `ParseIntPipe`
    * `ParseBoolPipe`
    * `ParseArrayPipe`
    * `ParseUUIDPipe`

    The `ValidationPipe` makes use of the powerful [class-validator](https://github.com/typestack/class-validator) package and its declarative validation decorators. The `ValidationPipe` provides a convenient approach to enforce validation rules for all incoming client payloads, where the specific rules are declared with simple annotations in local class/DTO declarations in each module.

{% code title="main.ts" %}
```typescript
async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  app.useGlobalPipes(
    new ValidationPipe({
      // error handling when failed to validate the body
      exceptionFactory: (validationErrors: ValidationError[] = []) => {
        const logger = app.get(Logger);
        logger.error(JSON.stringify(validationErrors));
        return new BadRequestException(validationErrors);
      },
      // transform into correct type based on type definition
      transform: true,
      // remove unlisted field
      whitelist: true,
    }),
  await app.listen(process.env.PORT ?? 3000);
}
bootstrap();
```
{% endcode %}

