Hi all,
Tiếp tục chương trình, chúng ta sẽ đi qua những cách tiếp cận cơ bản dành cho NestJS framework.
Topic cũ cho bạn nào chưa đọc: https://sethphat.com/sp-1014/em-yeu-khoa-hoc-typescript-nestjs
Tiến hành thoy nhé <3
Lưu ý, khi bạn đọc bài viết này, tôi assume bạn đã biết / có kiến thức về những thứ sau:
- JavaScript ES5, ES6, ES7 (biết rõ)
- TypeScript (sơ sơ cũng dc)
- NPM / Yarn (basic nhé, biết rõ)
1/ NestJS
Documentation: https://docs.nestjs.com/
Về cơ bản, NestJS là một framework để cho bạn build 1 NodeJS server-side webservice có hiệu quả cao, scale tốt. 100% support TypeScript.
Chơi đủ với 3 chiêu trò dev hiện nay là:
- OOP – Object-Oriented Programming
- FP – Functional Programming
- FRP – Functional Reactive Programming
Biết rõ thêm về NestJS thì lên documentation đọc nha các bạn =))
2/ Cài đặt NestJS CLI và tạo Project NestJS cho người mới bắt đầu
Cài cli:
npm i -g @nestjs/cli
Tạo project thông qua lệnh sau:
// usage
nest new <project-name>
// demo
nest new seth-phat-blog
Lưu ý với Linux/MacOS users: ko nên dùng sudo để cài nhé, cài global package cho user của bạn thoy để tránh permission issues.
Cài xong thì các bạn có thể vào thư mục project (Eg: cd seth-phat-blog), chạy thử “npm run start” / “yarn start”.
Nếu bạn access được http://localhost:3000 thì bạn đã cài thành công =))
3/ Structure cơ bản
Mở project bạn ra bằng 1 IDE/Editor của bạn (mình xài WebStorm <3). Vào thư mục src
Bạn sẽ thấy 5 files này:
Hiểu đơn giản nhất về từng file là:
- main.ts – là nơi để boot up framework
- app.module.ts – là nơi để bạn register service, controller / inject module, library,…
- Inject tại app.module là 1 injection cho toàn bộ modules nhỏ lẻ trong project, có nghĩa là những gì bạn injected ở đây thì toàn bộ modules riêng của bạn đều có thể sử dụng.
- app.controller.ts – là main controller của project, thường ta sẽ ko xài =))
- app.service.ts – là nơi bạn xử lý business logic cho app-level. Thường thì ta cũng sẽ ko xài
- app.controller.spec.ts – Unit Test cho app.controller.ts
4/ Modular Structure of NestJS
Cũng tương tự như tầng Application – nó là 1 global module. Và khi làm việc với NestJS, ta làm trên Modular Structure.
Một trong những cái hay của Module của NestJS là nó buộc bạn phải tách biệt rõ ràng các scopes trong Application của bạn. Ví dụ:
- User Module – scope User: CRUD, bu-di-nít (business) liên wan tới User sẽ bỏ trong đây hết (Including APIs)
- Chat Module – scope Chat: Mọi thứ liên quan tới Chat features,…
- …
Để Module của bạn dc inject vào NestJS’s lifecycle. Bạn cần register tại app.module.ts tại key imports.
Khi đó Module của bạn đã dc expose ra, và client có thể sử dụng specific-APIs trong Module bạn.
Ngoài ra bạn cũng ko cần expose cho Application-level module cũng dc. Khi đó Module của bạn sẽ là internal-module.
Module vẫn có thể giao tiếp với Module, khi đó chúng nó chỉ import lẫn nhau (tương tự trên Application), điều này để chúng ta quản lý Dependency Injection dễ dàng hơn 😀
4.1/ Basic
Tạo module mới thông qua CLI-command:
// Usage
nest generate module <module_name>
// Example
nest generate module users
Module naming convention: <name_module>.module.ts
Class module khi khởi tạo sẽ kèm annotation này: @Module()
4.2/ Module Definition
Thông qua annotation @Module, ta có thể:
- import những Module(s) mà Module này sẽ sử dụng – thông wa imports
- register những Controller(s) thuộc Module này – thông wa controllers
- define những Service(s) thuộc Module này – thông wa providers
- define những thứ thuộc Module này để các Module khác có thể sử dụng – thông wa exports
Định nghĩa Feature of Module:
The
UserController
andUserService
belong to the same application domain. As they are closely related, it makes sense to move them into a feature module. A feature module simply organizes code relevant for a specific feature, keeping code organized and establishing clear boundaries. This helps us manage complexity and develop with SOLID principles, especially as the size of the application and/or team grow.
Đơn giản là nó cùng domain, gói nó lại vào 1 Module để dễ quản lý, dễ grow up,… mà lại tuân thủ dc SOLID. Và dc cái như mình nói lúc nãy là đúng scope của nó.
5/ Controller
Cũng như tên gọi của nó. Controller đứng ra để xử lý HTTP Request, đúng như tên của nó là: “Điều Khiển”.
100% là ta ko nên xử lý Business Logic/Complex Task tại đây.
CLI để tạo Controller cho Module-level:
// Usage
nest generate controller <name>
// Demo
nest generate controller user
NestJS-CLI nó sẽ tự vào thư mục Module user và tạo ra user.controller.ts cho bạn. Kèm với user.controller.spec.ts để bạn viết Unit Test =))
Controller của NestJS cũng làm nhiệm vụ Routing luôn nhé các bạn. NestJS có cả bộ annotations dành cho vụ HTTP-Request/Routing/… dành cho Controller rùi. Chi tiết lên Documentation cho lẹ nè: NestJS Controller
Ở trong Controller, bạn có thể inject Service bạn muốn sử dụng tại hàm khởi tạo. NestJS sẽ handle vụ initialization cho bạn.
6/ Service / Provider
Gọi Service luôn cho đơn giản nhé. Như trên mình đã nói thì về Complex Task / Business Logic Handle / DB Handle / … mọi thứ ta nên để cho Service lo
Service là những class đi kèm với annotation là: @Injectable()

Như cái graph trên, Controller sẽ có thể inject những service(s) mà nó muốn sử dụng, mục đích cuối cùng thì Service fải trả về Result để thằng Controller nó trả về cho client :))
Service đứng ra làm reusable component. Các Controller/Service của Module khác cũng có thể sử dụng Service của Module kia (fải register nha)
Tạo Service qua CLI:
// Usage
nest generate service <name>
// Example
nest generate service user
Một file user.service.ts sẽ được tạo trong folder Module user
Về flow cơ bản cho 1 HTTP Request – Retrieve by ID như sau:
- /user/get/1
- Vào UserController
- Vào method getById
- Method getById sẽ gọi tới UserService và invoke cái hàm getById
- UserService query và trả về kết quả (kể cả có hay ko)
- Controller return kết quả về client
- Over
7/ Overall về NestJS dành cho người mới bắt đầu
Tất cả những gì mình viết ở đây là thứ cơ bản, nếu có gì ko đúng các bạn check lại documentation rồi réo mình cái để mình update lại nha =))
Thanks for reading.