npm install -g nest-cli
nest new project-name
- More: Reference
You can use nest cli to generate Service, Module, Controller, ... with supported flag
Example
nest g module module-name
nest g service module-name/services/serivce-name --no-spec --flat
nest g controller module-name/controllers/serivce-name --no-spec --flat
- More: Reference
- Interceptor
- Guard
- Filter
- Pipe
- Middleware
- Controller
- Service
Controll Flow: Middleware => Guard => Interceptor => Pipes => Controller => Filter
More: (Ref)
-
Throw excetion: Nestjs Common have basic Http Exeption: There are: HttpException, ForbiddenException,
-
Example
@Get()
async findAll() {
throw new HttpException('Forbidden', HttpStatus.FORBIDDEN);
}
-
You can custom http exception. (Reference)
-
You need to filter exception for easy handle error when you code Reference
Is a Design Pattern use Object Oriented Programing Idea
Avoid about Cicular dependency Reference
- Use TypeORM (or any ORM libarary), you can map to your database, code less... docs link
-
If you want create a basic CRUD API, You should apply repository pattern
-
Repository Pattern have three layers: Repository layer, Service layer, controller layer. Example.
-
Note: You can write Basic Repository Interface and Basic Repository Abstract to inherit from it, you can code less. You can reference about my code: Reference
- This example I use Cloudinary Example
-
I write a cache module use cache-manager lib. Code
-
Cache improves your app performace
-
You write CacheInterceptor and apply it
- Basic auth (Example) (Not recommend use this)
- I use passport lirary for support AT and RT
- I create 2 Guard (AT Guard and RT Guard)
- Apply to route or controller (Depends your application logic)
- Code: link
- PassportJS support 3rd login
- You need install PassportJS and Passport/Github
npm install @nestjs/passport passport passport-github
npm install --save-dev @types/passport-github
- Use Role Guard for authorize (between difference role)
- Example
- Need to use Casl Ability when You want guard route by User id together ( between 2 user same roles )
- Example
- Write a dockerfile for your app => image
# Specify the base image
FROM node:14
# Set the working directory
WORKDIR /app
# Copy package.json and package-lock.json to the working directory
COPY package*.json ./
# Install application dependencies
RUN npm install
# Copy the rest of the application files
COPY . .
# Specify the command to run the application
CMD ["npm", "start"]
- Run services for your app (Mysql, Redis, Elasticsearch,... )
version: '3.8'
services:
# MySQL service
mysql:
image: mysql
environment:
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
MYSQL_DATABASE: ${MYSQL_DATABASE}
volumes:
- mysql_data:/var/lib/mysql
ports:
- '3306:3306'
phpmyadmin:
image: phpmyadmin/phpmyadmin
environment:
PMA_HOST: mysql
PMA_USER: root
PMA_PASSWORD: ${MYSQL_ROOT_PASSWORD}
ports:
- '8080:80'
# Redis service
redis:
container_name: redis
image: redis:alpine
expose:
- 6379
ports:
- '6379:6379'
restart: unless-stopped
redis_commander:
container_name: redis_commander
image: rediscommander/redis-commander:latest
environment:
- REDIS_HOSTS=local:redis:6379
ports:
- '8088:8081'
depends_on:
- redis
volumes:
mysql_data:
networks:
test:
driver: bridge
- I use event emitter for auth module.
- Explain: when i sign up a accout, the app will send an email to accout's email. If I write mail service into signup => when i signup, i have to wait mail sent => it's not good for perfomance => I use event emitter to emit an user signup event, when this event emitter => email service will send an email
- Code: link
- I use Queue to sync shop data form an API
- Explain: when this fetch service run, I add a sync shop queue => shop data will sync into my database. This job use a lot of Resource so i use queue to run this
- Code: link
-
I use Websocket and Socket.IO for chatting and notification
-
Notification: When i create an order => i will emit an event create order => this websocket listen, create an room and user, shop can chat in this room (This room name created by order id)
-
Code: link
- A database design
- Example:
@Entity({ name: "setting" })
export class Setting extends BaseEntity {
// ...
key: SETTING_KEY;
value: string;
// ...
}
- More: My setting module link