티스토리 뷰
OneToMany, ManyToOne, ManyToMany 를 작성해보자.
OneToMany, ManyToOne
앞서 작성 했던 User에 할일 목록인 task 컬럼을 추가하자.
이는 유저입장에서는 task와 OneToMany 관계이며 Task 입장에서는 ManyToOne 관계이다.
먼저 task.entity.ts
파일을 만들고 아래와 같이 작성했다.
import { Column, Entity, ManyToOne, PrimaryGeneratedColumn } from 'typeorm'
import { User } from './user.entity'
@Entity()
export class Task {
@PrimaryGeneratedColumn()
id: number
@Column()
name: string
@ManyToOne(() => User, (user) => user.task, { onDelete: 'SET NULL' })
user: User
constructor(name) {
this.name = name
}
}
다음 user.entity.ts
에 다음 코드를 추가했다.
@OneToMany(() => Task, (task) => task.user, { nullable: true })
task: Task[]
이제 할 일 목록을 추가하는 작업을 추가해보자.
먼저 create-task.dto.ts
를 작성했다.
import { IsString } from 'class-validator'
export class createTaskDto {
@IsString()
readonly name: string
}
그 다음 controller
와 service
에 task를 추가하는 작업을 추가했다.
/user/task/:id
로 patch요청과 함께 task 작업을 json형태로 보내면
id에 해당하는 유저에 task를 추가한다.
//user.controller.ts
@Patch('task/:id')
createTask(@Param('id') userId: number, @Body() taskData: createTaskDto) {
return this.userService.createTask(userId, taskData)
}
//user.service.ts
async createTask(id: number, taskData: createTaskDto) {
const user = await this.userRepository.findOne(id, {
relations: ['task'],
})
const task = await this.taskRepository.save(taskData)
user.task.push(task)
return await this.userRepository.save(user)
}
이렇게 작성한 다음 patch요청을 두번정도 보낸다음에 결과를 확인 해 보았다.
{
"id": 1,
"name": "j342y2o",
"gender": "Male",
"age": 26,
"carId": null,
"createdAt": "2021-07-30T07:12:33.535Z",
"updatedAt": "2021-07-30T07:15:48.277Z",
"car": null,
"task": [
{
"name": "study",
"id": 2
},
{
"name": "sleep",
"id": 3
}
]
}
이렇게 task에 할일이 추가되어 결과가 돌아오는 것을 확인할 수 있다.
ManyToMany
마지막으로 ManyToMany를 작성해 보자.
이번엔 User와 meeting 관계를 작성할 것이다.
유저는 여러개의 meeting을 가질 수 있고, meeting은 여러개의 유저를 가질 수 있다.
먼저 metting.entity.ts
를 만들었다.
import {
Column,
Entity,
JoinColumn,
ManyToMany,
OneToOne,
PrimaryGeneratedColumn,
} from 'typeorm'
import { User } from './user.entity'
@Entity()
export class Meeting {
@PrimaryGeneratedColumn()
id: number
@Column()
name: string
@OneToOne(() => User)
@JoinColumn()
owner: User
@ManyToMany(() => User, (user) => user.meetings)
user: User[]
}
그리고 user.entity.ts
를 수정했다.
@ManyToMany(() => Meeting, (meetings) => meetings.user)
@JoinTable()
meetings: Meeting[]
ManyToMany 관계일 경우 @JoinTable()
을 설정해줘야한다.
@JoinTable() is required for @ManyToMany relations. You must put @JoinTable on one (owning) side of relation.
typeorm 공식문서에서도 이 내용을 말해주고 있다.
이제 meeting을 추가하고 user와 연결해보자.
meetin을 개설하는 방법은 /user/meeting
에 post요청으로 meeting의 name과 owner의 id를 담아서 보내면 된다.
//user.controller.ts
@Post('meeting')
createMeeting(@Body() MeetingInfo: createMeetingDto) {
return this.userService.createMeeting(MeetingInfo)
}
//user.service.ts
async createMeeting(meetingInfo: createMeetingDto) {
const { owner, name } = meetingInfo
const user = await this.userRepository.findOne(owner, {
relations: ['meetings'],
})
const meeting = await this.meetingRepository.save({
name: name,
owner: user,
})
user.meetings.push(meeting)
await this.userRepository.save(user)
}
이렇게 코드를 작성하고
{
"name" : "meeting1",
"owner" : 1
}
로 POST요청을 보내고 결과를 확인해보았다.
{
"id": 1,
"name": "jonyo",
"gender": "Male",
"age": 26,
"carId": null,
"createdAt": "2021-07-30T08:38:52.268Z",
"updatedAt": "2021-07-30T08:38:52.268Z",
"car": null,
"task": [],
"meetings": [
{
"id": 1,
"name": "meeting1"
}
]
}
이렇게 meeting정보가 잘 들어간 것을 볼 수 있다.
이제 이렇게 개설된 meeting에 유저를 추가해보자.
/user/meeting/:id
로 patch요청을 보내면서 body에 userId를 담으면 해당 meeting에 대해 유저를 추가하게 된다.
//user.controller.ts
@Patch('meeting/:id')
addUserToMeeting(@Param('id') meetingId: number, @Body() data: any) {
this.userService.addUserToMeeting(meetingId, data.userId)
}
//user.service.ts
async addUserToMeeting(meetingId: number, userId: number) {
const user = await this.userRepository.findOne(userId, {
relations: ['meetings'],
})
const meeting = await this.meetingRepository.findOne(meetingId)
user.meetings.push(meeting)
await this.userRepository.save(user)
}
이제 정상적으로 결과가 잘 나오는지 확인하기 위해 meeting id를 가지고 meeting의 정보를 가져오는 함수를 작성해보자.
//user.controller.ts
@Get('meeting/:id')
getMeeting(@Param('id') meetingId: number) {
return this.userService.getMeeting(meetingId)
}
//user.service.ts
async getMeeting(meetingId: number): Promise<Meeting> {
const meeting = await this.meetingRepository.findOne(meetingId, {
relations: ['owner', 'user'],
})
if (!meeting)
throw new NotFoundException(`Not found meeting with the id ${meetingId}`)
return meeting
}
앞서 생성한 1번 미팅에 대한 정보를 확인하기 위해 /user/meeting/1
로 Get요청을 보내보았다.
{
"id": 1,
"name": "meeting1",
"owner": {
"id": 1,
"name": "jonyo",
"gender": "Male",
"age": 26,
"carId": null,
"createdAt": "2021-07-30T08:38:52.268Z",
"updatedAt": "2021-07-30T08:38:52.268Z"
},
"user": [
{
"id": 1,
"name": "jonyo",
"gender": "Male",
"age": 26,
"carId": null,
"createdAt": "2021-07-30T08:38:52.268Z",
"updatedAt": "2021-07-30T08:38:52.268Z"
},
{
"id": 2,
"name": "jonyo1",
"gender": "Male",
"age": 26,
"carId": null,
"createdAt": "2021-07-30T08:38:55.502Z",
"updatedAt": "2021-07-30T08:38:55.502Z"
}
]
}
이런식으로 meeting에 추가된 유저의 정보를 확인할 수 있다.
Nest.js는 확실히 매우 편리하다.
node를 쓰다가 express를 쓰면 매우 편리함을 느낄 수 있는데 nest는 express보다 편리하다.
또 기본적으로 프로젝트의 구조를 잡아주기에 여기서 시키는대로 따라하면 유지보수하기 쉬운 코드를 자동적으로 짤 수 있다.
nest의 가장 기본 중 기본만 다뤄보았는데도 많은 곳에서 편리하다는 것을 느꼈다. 여러가지 기능들을 모듈화 하면서 구조적인 프로젝트를 만들 수 있었다.
typeORM은 처음 사용해보는거라 너무 어려웠다. 아직도 이게 맞는지 헷갈린다. 그래도 타입을 지원한다는 점에서 매우 강력한 도구인 것 같다. 조금 더 숙련된다면 좋을 것 같다.
'Node.js' 카테고리의 다른 글
Nest.js + typeORM 으로 REST API 서버 만들기 (6) (0) | 2021.07.30 |
---|---|
Nest.js + typeORM 으로 REST API 서버 만들기 (5) (0) | 2021.07.29 |
Nest.js + typeORM 으로 REST API 서버 만들기 (4) (0) | 2021.07.29 |
Nest.js + typeORM 으로 REST API 서버 만들기 (3) (0) | 2021.07.29 |
Nest.js + typeORM 으로 REST API 서버 만들기 (2) (0) | 2021.07.29 |
- Total
- Today
- Yesterday
- Computer Architecture
- 구현
- 시뮬레이션
- 그래프
- 그리디
- ReactNative
- nestjs
- 예외처리
- 벨만포드
- java
- 컴퓨터 구조
- 자바스크립트
- 백준
- 컴퓨터 통신
- typeORM
- 동적계획법
- BFS
- 자바
- 스레드
- nest.js
- nodeJS
- node.js
- 중앙대학교
- boj
- 재귀
- 세그먼트 트리
- 투포인터
- 백트래킹
- dfs
- 알고리즘
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |