M
Modules & Controllers
Type-safe NestJS modules, controllers, and dependency injection with decorators.
Code
typescript
1// user.entity.ts2export class User {3 id: number;4 name: string;5 email: string;6 role: "admin" | "user";7 createdAt: Date;8 updatedAt: Date;9}10 11// dto/create-user.dto.ts12import { IsString, IsEmail, IsEnum, IsOptional, MinLength } from "class-validator";13 14export class CreateUserDto {15 @IsString()16 @MinLength(2)17 name: string;18 19 @IsEmail()20 email: string;21 22 @IsString()23 @MinLength(8)24 password: string;25 26 @IsOptional()27 @IsEnum(["admin", "user"])28 role?: "admin" | "user";29}30 31// dto/update-user.dto.ts32import { PartialType } from "@nestjs/mapped-types";33 34export class UpdateUserDto extends PartialType(CreateUserDto) {}35 36// dto/query-user.dto.ts37import { IsOptional, IsInt, Min, Max, IsEnum } from "class-validator";38import { Type } from "class-transformer";39 40export class QueryUserDto {41 @IsOptional()42 @Type(() => Number)43 @IsInt()44 @Min(1)45 page?: number = 1;46 47 @IsOptional()48 @Type(() => Number)49 @IsInt()50 @Min(1)51 @Max(100)52 limit?: number = 10;53 54 @IsOptional()55 @IsEnum(["admin", "user"])56 role?: "admin" | "user";57 58 @IsOptional()59 @IsString()60 search?: string;61}62 63// user.service.ts64import { Injectable, NotFoundException, ConflictException } from "@nestjs/common";65 66@Injectable()67export class UserService {68 private users: User[] = [];69 private nextId = 1;70 71 async findAll(query: QueryUserDto): Promise<{ data: User[]; total: number }> {72 let result = this.users;73 74 if (query.role) {75 result = result.filter((u) => u.role === query.role);76 }77 78 if (query.search) {79 const search = query.search.toLowerCase();80 result = result.filter(81 (u) =>82 u.name.toLowerCase().includes(search) ||83 u.email.toLowerCase().includes(search)84 );85 }86 87 const total = result.length;88 const start = (query.page! - 1) * query.limit!;89 const data = result.slice(start, start + query.limit!);90 91 return { data, total };92 }93 94 async findOne(id: number): Promise<User> {95 const user = this.users.find((u) => u.id === id);96 if (!user) {97 throw new NotFoundException(`User with ID ${id} not found`);98 }99 return user;100 }101 102 async create(dto: CreateUserDto): Promise<User> {103 const existingUser = this.users.find((u) => u.email === dto.email);104 if (existingUser) {105 throw new ConflictException("Email already in use");106 }107 108 const user: User = {109 id: this.nextId++,110 name: dto.name,111 email: dto.email,112 role: dto.role || "user",113 createdAt: new Date(),114 updatedAt: new Date(),115 };116 117 this.users.push(user);118 return user;119 }120 121 async update(id: number, dto: UpdateUserDto): Promise<User> {122 const user = await this.findOne(id);123 124 if (dto.email && dto.email !== user.email) {125 const existingUser = this.users.find((u) => u.email === dto.email);126 if (existingUser) {127 throw new ConflictException("Email already in use");128 }129 }130 131 Object.assign(user, dto, { updatedAt: new Date() });132 return user;133 }134 135 async remove(id: number): Promise<void> {136 const index = this.users.findIndex((u) => u.id === id);137 if (index === -1) {138 throw new NotFoundException(`User with ID ${id} not found`);139 }140 this.users.splice(index, 1);141 }142}143 144// user.controller.ts145import {146 Controller,147 Get,148 Post,149 Patch,150 Delete,151 Body,152 Param,153 Query,154 ParseIntPipe,155 HttpCode,156 HttpStatus,157} from "@nestjs/common";158 159@Controller("users")160export class UserController {161 constructor(private readonly userService: UserService) {}162 163 @Get()164 async findAll(@Query() query: QueryUserDto) {165 return this.userService.findAll(query);166 }167 168 @Get(":id")169 async findOne(@Param("id", ParseIntPipe) id: number) {170 return this.userService.findOne(id);171 }172 173 @Post()174 @HttpCode(HttpStatus.CREATED)175 async create(@Body() dto: CreateUserDto) {176 return this.userService.create(dto);177 }178 179 @Patch(":id")180 async update(181 @Param("id", ParseIntPipe) id: number,182 @Body() dto: UpdateUserDto183 ) {184 return this.userService.update(id, dto);185 }186 187 @Delete(":id")188 @HttpCode(HttpStatus.NO_CONTENT)189 async remove(@Param("id", ParseIntPipe) id: number) {190 return this.userService.remove(id);191 }192}193 194// user.module.ts195import { Module } from "@nestjs/common";196 197@Module({198 controllers: [UserController],199 providers: [UserService],200 exports: [UserService],201})202export class UserModule {}Run this example locally
$ npx @nestjs/cli new my-app