📚 TUẦN 1: NESTJS FUNDAMENTALS & PROJECT SETUP
🎯 Mục tiêu tuần này: Hiểu sâu kiến trúc NestJS core, setup môi trường phát triển hoàn chỉnh
1. CHỨC NĂNG CẦN HOÀN THÀNH
| STT | Chức năng | Mô tả | Output |
|---|---|---|---|
| 1.1 | Setup Project | Khởi tạo NestJS project với cấu trúc modules | Project chạy được trên port 3000 |
| 1.2 | Docker Environment | Setup Docker Compose cho PostgreSQL + Redis | Containers running |
| 1.3 | Hiểu NestJS Architecture | Module, Provider, Controller | Code demo đầy đủ |
| 1.4 | Tạo QuizModule (Skeleton) | Cấu trúc module cơ bản | CRUD endpoints skeleton |
2. KIẾN THỨC CẦN NẮM VỮNG
2.1 NestJS Core Concepts
📖 Module
Khái niệm:
- Module là container đóng gói các thành phần liên quan (controllers, providers, imports)
- Mỗi NestJS app có ít nhất 1 root module (
AppModule) - Modules giúp tổ chức code theo domain/feature
Core Component:
@Module({
imports: [], // Các module khác cần sử dụng
controllers: [], // Các controller trong module này
providers: [], // Các service, repository...
exports: [], // Providers được export cho module khác dùng
})
export class QuizModule {}
Use Cases:
- Feature module:
QuizModule,AuthModule,GameModule - Shared module:
DatabaseModule,LoggerModule - Dynamic module: Config module với forRoot/forFeature
Best Practices:
- ✅ Mỗi feature có module riêng
- ✅ Tránh circular dependencies giữa modules
- ✅ Export chỉ những gì cần thiết
- ❌ Không để tất cả trong AppModule (god module)
📖 Controller
Khái niệm:
- Xử lý incoming HTTP requests
- Định nghĩa routes và HTTP methods
- Trả về response cho client
Core Component:
@Controller('quizzes') // Route prefix: /quizzes
export class QuizController {
constructor(private readonly quizService: QuizService) {}
@Get() // GET /quizzes
findAll() {
return this.quizService.findAll();
}
@Get(':id') // GET /quizzes/:id
findOne(@Param('id') id: string) {
return this.quizService.findOne(id);
}
@Post() // POST /quizzes
create(@Body() createQuizDto: CreateQuizDto) {
return this.quizService.create(createQuizDto);
}
}
Decorators quan trọng:
| Decorator | Mục đích |
|---|---|
@Controller('path') | Định nghĩa route prefix |
@Get(), @Post(), @Put(), @Delete() | HTTP methods |
@Param('id') | Lấy URL parameter |
@Body() | Lấy request body |
@Query() | Lấy query string |
Best Practices:
- ✅ Controller chỉ xử lý HTTP layer, không chứa business logic
- ✅ Delegate logic cho Service
- ✅ Validate input bằng DTOs + Pipes
📖 Provider & Dependency Injection (DI)
Khái niệm:
- Provider = class có thể inject vào những class khác
- DI = framework tự động tạo instance và inject dependencies
- Giảm coupling, dễ test, dễ maintain
Core Component:
// 1. Định nghĩa Provider
@Injectable() // Decorator đánh dấu là Provider
export class QuizService {
private quizzes = [];
findAll() {
return this.quizzes;
}
create(quiz: CreateQuizDto) {
this.quizzes.push(quiz);
return quiz;
}
}
// 2. Đăng ký trong Module
@Module({
providers: [QuizService], // Đăng ký Provider
controllers: [QuizController],
})
export class QuizModule {}
// 3. Inject vào Controller
@Controller('quizzes')
export class QuizController {
// NestJS tự động inject QuizService instance
constructor(private readonly quizService: QuizService) {}
}
Cách DI hoạt động:
1. App start → NestJS scan tất cả modules
2. Tìm các class có @Injectable()
3. Tạo container chứa các instances (singleton by default)
4. Khi có class cần dependency → Inject instance từ container
Use Cases:
- Services: Business logic (
QuizService,AuthService) - Repositories: Data access layer
- Factories: Tạo objects phức tạp
- Helpers: Utility functions
Best Practices:
- ✅ Một service = một responsibility
- ✅ Inject qua constructor (không inject qua property)
- ✅ Sử dụng interfaces + custom providers khi cần linh hoạt
2.2 NestJS Request Lifecycle
Incoming Request
↓
Middleware → Xử lý trước controller (logging, cors...)
↓
Guards → Kiểm tra authorization (JWT valid?)
↓
Interceptors → Transform request (before)
↓
Pipes → Validate & transform data
↓
Controller → Handle request
↓
Service → Business logic
↓
Interceptors → Transform response (after)
↓
Response sent
3. STEP BY STEP TRIỂN KHAI
Bước 1: Setup NestJS Project
# Cài đặt NestJS CLI
npm install -g @nestjs/cli
# Tạo project mới
nest new quiz-realtime
# Chọn npm hoặc yarn
# Cấu trúc project sau khi tạo:
quiz-realtime/
├── src/
│ ├── app.controller.ts # Root controller (demo)
│ ├── app.module.ts # Root module
│ ├── app.service.ts # Root service (demo)
│ └── main.ts # Entry point
├── test/
├── package.json
└── tsconfig.json
Bước 2: Tạo Docker Compose
# docker-compose.yml
version: '3.8'
services:
postgres:
image: postgres:15-alpine
container_name: quiz_postgres
environment:
POSTGRES_USER: quiz_user
POSTGRES_PASSWORD: quiz_password
POSTGRES_DB: quiz_db
ports:
- "5432:5432"
volumes:
- postgres_data:/var/lib/postgresql/data
redis:
image: redis:7-alpine
container_name: quiz_redis
ports:
- "6379:6379"
volumes:
postgres_data:
# Chạy containers
docker-compose up -d
# Kiểm tra
docker ps
Bước 3: Tạo QuizModule
# Tạo module
nest generate module quiz
# Tạo controller
nest generate controller quiz
# Tạo service
nest generate service quiz
Kết quả:
src/
├── quiz/
│ ├── quiz.module.ts
│ ├── quiz.controller.ts
│ ├── quiz.service.ts
│ └── quiz.controller.spec.ts # Unit test
└── app.module.ts # Tự động import QuizModule