라이브러리, 프레임워크/TypeORM
[TypeORM + NestJS] 일기 생성 API - oneToMany, manyToMany save 로직 기록
dv_jamie
2023. 1. 1. 22:24
개요
- 하나의 일기에 여러 개의 이미지들과 테마들을 함께 등록할 수 있음
- 일기, 이미지, 테마는 각각 테이블을 하나씩 갖고 있음
- 테마는 유저가 수정할 수 없는 값으로, 데이터들을 미리 저장해뒀음
관계 설정
- 일기와 이미지 : OneToMany (하나의 일기에 여러 개의 이미지 등록 가능)
- 일기와 테마 : ManyToMany (각 일기는 여러개의 테마, 각 테마는 여러 개의 일기를 가질 수 있음)
일기 생성 API
// create-diary.dto.ts
import { PickType } from "@nestjs/mapped-types";
import { IsNumber, IsString } from 'class-validator';
import { Diary } from "../entities/diary.entity";
export class CreateDiaryDto extends PickType(Diary, [
// 유저가 입력하는 일기의 내용
'content',
] as const) {
// 테마는 이미 등록되어 있으므로 유저가 선택한 테마 id를 배열로 받을 수 있음
@IsNumber({}, { each: true })
themeIds: number[]
// 이미지는 url을 배열로 받음
@IsString({ each: true })
imageUrls: string[]
}
// diaries.service.ts
async create(
reqId: number, // 작성자는 request 객체로 받음
createDiaryDto: CreateDiaryDto
):Promise<ResponseDto> {
const findWriter = await this.usersService.findOneById(reqId)
const writer = findWriter.data
const { content, themeIds, imageUrls } = createDiaryDto
// diary 엔티티에서 themes: Theme[]로 타입을 지정함
// 테마를 엔티티로 저장 + 해당 테마 없을 경우의 예외 처리 위해
// id값으로 theme 엔티티를 find
const themes:Theme[] = []
for(const id of themeIds) {
const theme = await this.themesService.findOneById(id)
themes.push(theme)
}
// 위에서 만든 Theme 엔티티 배열을 아래와 같이 함께 save하여 일기 생성
const createdDiary = await this.diaryRepository.save({
content,
writer,
themes
})
// Image 객체 생성 후 url과 위에 생성했던 diary를 담아 save
for(const url of imageUrls) {
const newImage = new Image
newImage.url = url
newImage.diary = createdDiary
await this.imagesService.create(newImage) // create 함수는 아래 코드블럭 참고
}
return {
status: 200,
data: {}
};
}
// images.service.ts
async create(image: Image) {
const createdImages = await this.imageRepository.save(image)
return createdImages
}