Appearance
Commands
When a user needs to input data into the application, they must send this data in the body of a request. This body encapsulates the necessary data to perform an operation. This body is called the command or DTO (Data Transfer Object).
A command in NestJS is a simple class with properties. We use the class-validator package to validate this body. The validation module in the template project validates all body requests by default.
Example
INFO
Don't forget to add @ApiProperty()
decorators to generate OpenAPI documentation.
Below is an example of a command to create a new product.
typescript
export class CreateProductCommand {
@ApiProperty({ type: String, example: 'Wise Cookies' })
@IsString()
@IsNotEmpty()
name: string
@ApiProperty({ type: Number })
@IsNumber()
@IsPositive({ message: 'Price must be a positive number' })
price: number
@ApiProperty({ type: Number })
@IsNumber()
@Min(0, { message: 'Stock must be at least 0' })
stock: number
@ApiProperty({ enum: ProductCategory, enumName: 'ProductCategory', required: false })
@IsOptional()
@IsEnum(ProductCategory)
category?: ProductCategory
@ApiProperty({ type: String, isArray: true })
@IsArray()
@IsString({ each: true })
@ArrayMinSize(1, { message: 'There should be at least 1 tag' })
tags: string[]
}
If the provided decorators in the class-validator package are not sufficient for your needs, you can always create a custom validator by implementing the
ValidatorConstraintInterface
interface.
When the command is ready, you can use it in your controller by applying the @Body()
decorator before the function parameter.
typescript
@Controller('products')
export class CreateProductController {
@Post()
async createOne(
@Body() command: CreateProductCommand
) {
await this.useCase.createProduct(command);
}
}
INFO
Make sure to import the command without the type prefix.
NestJS will otherwise not be able to validate the command.
typescript
✅ import { CreateProductCommand } from './create-product.command';
❌ import type { CreateProductCommand } from './create-product.command.ts';