Nest.js CLI Generation Commands
The Nest.js CLI provides convenient commands to scaffold module components:
# Generate module
nest g mo
# Generate controller
nest g co
# Generate service
nest g s
Additional generators create entity classes, DTOs, and GraphQL-specific components.
For generating complete resources with all components at once:
nest g resource
This creates the module, service, controller, entity classes, DTOs, and test files.
Disabling Test File Generation
To skip test file creation, use the --no-spec flag:
nest g resource product --no-spec
Alternatively, configure this in nest-cli.json:
{
"generateOptions": {
"spec": false
}
}
When running nest g res user from the project root, generated files appear in src/user/. Running from subdirectories creates files relative to that location, but nest-cli.json settings only apply when executing from the root directory. The generated UserModule is automatically imported into AppModule.
Understanding Scaffolded Code
Dependency Injection in Controllers
The generated controller uses constructor injection to obtain the service instance:
@Controller('user')
export class UserController {
constructor(private readonly userService: UserService) {}
}
Route Decorators
The @Controller('user') decorator sets the base path for all routes within the controller. Each method uses decorators like @Get() or @Post() to define HTTP methods, with route parameters specified in parantheses:
@Get()
findAll(): User[] {
return this.userService.findAll();
}
@Get(':id')
findOne(@Param('id') id: string): User {
return this.userService.findOne(id);
}
Dynamic route segments use colon notation. The pattern 'ab*cd' matches paths like abcd, ab_cd, and abecd. Special characters ?, +, *, and () function as regex subsets. Hyphens and dots are interpreted literally.
Response Customization
By default, GET returns 200 and POST returns 201. Override these with @HttpCode():
@HttpCode(204)
@Delete(':id')
remove(@Param('id') id: string): void {
this.userService.remove(id);
}
Customize headers:
@Header('Cache-Control', 'none')
Redirect requests:
@Redirect('https://example.com', 301)
Methods can return Promise<T> for async operations.
Parameter Extraction
Access route parameters with @Param():
@Get(':id')
findOne(@Param('id') id: string): User {
return this.userService.findOne(id);
}
Query parameters use @Query():
@Get()
findFiltered(@Query('status') status: string): User[] {
return this.userService.findByStatus(status);
}
Request body data requires @Body():
@Post()
create(@Body() createUserDto: CreateUserDto): User {
return this.userService.create(createUserDto);
}
Payload Transformation with Pipes
Raw JavaScript objects from requests need conversion to typed DTO instances. Interfaces get erased during compilation, so use classes instead:
@Patch(':id')
update(
@Param('id') id: string,
@Body() updateUserDto: UpdateUserDto
): User {
return this.userService.update(id, updateUserDto);
}
Enable automatic transformation in main.ts using ValidationPipe:
app.useGlobalPipes(
new ValidationPipe({
transform: true,
enableDebugMessages: true,
disableErrorMessages: false,
forbidUnknownValues: false,
}),
);
The transform: true option converts incoming data to DTO class instances. This works for body, param, and query data.
Input Validation Strategies
Schema-Based Validasion
Define validation within DTO classes using decorators from class-validator:
npm i --save class-validator class-transformer
import { IsString, IsInt, IsOptional } from 'class-validator';
export class CreateUserDto {
@IsString()
username: string;
@IsInt()
age: number;
@IsOptional()
email?: string;
}
This approach keeps the DTO as the single source of truth without requiring separate validation classes.
The built-in ValidationPipe automatically applies these decorators, providing validation out of the box when configured globally.
Zod Schema Validation
Alternative validation uses the Zod library with its schema definition approach.