Chào mừng các bạn trở lại với series tutorial Nestjs của mình.
Nói chung là học cái nestjs này nó cũng đơn giản nhưng mà “people make it complicated” nên mình sẽ giúp em các bạn cảm thấy enjoy cái framework này 😂 😂 😂 – theo danh ca Chipu
Index series
- Giới thiệu về setup repository + typeorm.
- Xác thực người dùng trong Nestjs sử dụng Passport JWT.
- Tiếp tục series mình cùng các bạn sẽ tìm hiểu vể Relationship trong Nestjs + Typeorm. Bắt đầu nhé
1. Setting base
-
Ở bài viết về setup repository + typeorm mình đã setting rất chi tiết rồi. mọi người có thể tham khảo lại bài viết tại đây
-
Cụ thể: ở đây mình sẽ chỉ lấy ra thông tin user bằng id gửi lên function findById($id)
Trong user.service.ts :
import{ UsersRepository }from'./users.repository';... @Injectable()exportclassUsersService{constructor(@InjectRepository(UsersRepository)private usersRepository: UsersRepository,){}asyncfindById( id: number, relations: string[]=[], throwsException =false,): Promise<UserEntity>{returnawaitthis.usersRepository.getEntityById( id, relations, throwsException,);}}
Trong user.repository.ts :
import{ UsersService }from'./users.service';... @Injectable()exportclassUsersService{constructor(@InjectRepository(UsersRepository)private usersRepository: UsersRepository,){}asyncfindById( id: number, relations: string[]=[], throwsException =false,): Promise<UserEntity>{returnawaitthis.usersRepository.getEntityById( id, relations, throwsException,);}}
2. One-To-One
-
Định nghĩa table
users table :id name email password int increment varchar varchar varchar profiles table
id user_id avatar address phone gender int increment int varchar varchar varchar varchar -
Define relationship in entity
Định nghĩa user.entity.ts :import{ IUser }from'../interfaces/user.interface';... @Entity({ name:'users'})exportclassUserimplementsIUser{ @PrimaryGeneratedColumn() id: string; @Column({ unique:true, length:255}) email: string; @Column({ name:'password', length:255}) password: string; @CreateDateColumn({ name:'created_at', type:'timestamp', nullable:true}) createdAt: Date; @UpdateDateColumn({ name:'updated_at', type:'timestamp', nullable:true}) updatedAt: Date;// define relationship with profiles table @OneToOne(()=> Profile,(profile)=> profile.user) profile: Profile;}
Định nghĩa profile.entity.ts :
import{ User }from'./entities/user.entity';... @EntityRepository(User)exportclassUsersRepository{...//function get user by id and relationshipasyncgetEntityById( id: number, relations: string[]=[],): Promise<UserEntity |null>{returnawaitthis.findOne({ where:{ id }, relations,}).then((entity)=>{if(!entity){return Promise.reject(newNotFoundException('Model not found'));}return Promise.resolve(entity ?this.transform(entity):null);});}transform(model: User): UserEntity {const transformOptions ={};returnplainToClass( UserEntity,classToPlain(model, transformOptions), transformOptions,);}
-
Get data User with Profile
Trong user.controller.ts :
import{ UsersService }from'./users.service';... @Controller('users')exportclassUsersController{constructor(private readonly usersService: UsersService){}... @Get('conversation/:id')asyncuserConversation(@Param() params): Promise<UserEntity>{const user =awaitthis.usersService.findById(params.id,['profile',]);this.throwUserNotFound(user);return user;}...}
còn đây sẽ là response
{"id":"13","name":"duong","email":"[email protected]","password":"$2b$12$JDj6D0RIjpGdd4tAGO/BMOqUxmq.7tEGIvWHtJfbm6MfxIeXyBrGW","createdAt":"2021-10-10T06:56:06.000Z","updatedAt":"2021-10-10T06:56:06.000Z","profile":{"id":"2","user_id":"13","avatar":null,"phone":"+84999999999","createdAt":"2021-10-16T10:51:49.000Z","updatedAt":"2021-10-16T10:51:49.000Z"},}
3. One-To-Many
-
Định nghĩa table
users table :id name email password int increment varchar varchar varchar messages table
id user_id conversation_id message int increment int int varchar -
Define relationship in entity
Định nghĩa user.entity.ts :
import{ IUser }from'../interfaces/user.interface';... @Entity({ name:'users'})exportclassUserimplementsIUser{... @OneToMany(()=> Message,(message)=> message.user) messages?: Message[];}
Định nghĩa messages.entity.ts
import{ IUser }from'../interfaces/user.interface';... @Entity({ name:'messages'})exportclassMessageimplementsIMessage{... @ManyToOne(()=> User,(user)=> user.messages) @JoinColumn({ name:'user_id'}) user?: User;}
-
Get data User with Profile
Trong user.controller.ts :
import{ UsersService }from'./users.service';... @Controller('users')exportclassUsersController{constructor(private readonly usersService: UsersService){}... @Get('conversation/:id')asyncuserConversation(@Param() params): Promise<UserEntity>{const user =awaitthis.usersService.findById(params.id,['messages',]);this.throwUserNotFound(user);return user;}...}
còn đây sẽ là response
{"id":"13","name":"duong","email":"[email protected]","messages":[{"id":"1","conversation_id":"1","user_id":"12","message":"hello xuan duong 2",},{"id":"2","conversation_id":"1","user_id":"12","message":"hello xuan duong 2",},]}
4. Many-To-Many
-
Định nghĩa table
users table :id name email password int increment varchar varchar varchar conversations table :
id title description …. int increment varchar varchar varchar user_conversation table
id user_id conversation_id int int int -
Define relationship in entity
Định nghĩa user.entity.ts :
@Entity({ name:'users'})exportclassUserimplementsIUser{... @ManyToMany(()=> Conversation,(conversations)=> conversations.users) @JoinTable({ name:'user_conversation', joinColumn:{ name:'user_id', referencedColumnName:'id'}, inverseJoinColumn:{ name:'conversation_id'},}) conversations: Conversation[];}
conversation.entity.ts :
@Entity({ name:'conversations'})exportclassConversationimplementsIConversation{... @ManyToMany(()=> User,(users)=> users.conversations) @JoinTable({ name:'user_conversation', joinColumn:{ name:'conversation_id', referencedColumnName:'id'}, inverseJoinColumn:{ name:'user_id'},}) users: User[];}
- Get data User with Profile
Trong user.controller.ts :
import{ UsersService }from'./users.service';... @Controller('users')exportclassUsersController{constructor(private readonly usersService: UsersService){}... @Get('conversation/:id')asyncuserConversation(@Param() params): Promise<UserEntity>{const user =awaitthis.usersService.findById(params.id,['conversations','conversations.messages',// lấy ra luôn các message trong converstion => nhớ định nghĩa relationship nhé]);this.throwUserNotFound(user);return user;}...}
5. Kết luận
-
Qua bài viết này mình đã giới thiệu cho các bạn relationship trong typeorm. nếu có khó khắn hoặc thắc mặc đừng ngại ngần comment ở dưới, Nếu bài viết hay và hữu ích thì cho mình xin 1 upvote.
-
Từ cấu trúc bảng mình đã xây dựn ở trên , ở bài tiếp theo mình sẽ giới thiệu với các bạn về chat realtime sử dụng :
Server: Nestjs + socket.io
Client: React + Redux saga
Thank you!
Nguồn: viblo.asia