스프링도 게시판, 게시글 구현까지는 쉬웠다! 여기까지는...
구현은 했는데 ① JWT 인증에서 filter 적용하는 방법을 최신버전 docs가 잘 이해되지 않았고, ② 구버전으로 돌아가서 한다 해도 방법을 이해 못하겠어서 스프링을 포기했었다.
filter만 어떻게 하면 될 거 같은데... 하던게 거의 한주
Nest는 Guard 하나만으로도 할 수 있어서 편했다!
Guard를 건너뛸 수 있는 방법도 있어서 편했다!
FastAPI도 꽤 편했다. 다만 여기서는 내가 코드를 잘 관리하지 못해서 파일이 너무 중구난방한 것.
추가로 이때는 docs를 안보고 다른 사람이 짠거 그대로 들고와서 적용했던거라 작동 방식은 몰랐다.
↑ 이거 때문에 Velog 작성을 하고 있는 중!
새로운 기술을 배워보기도 해야해서 문서로 남긴다.
nest g resource boards ← 게시판
nest g resource essays ← 게시글
nest g resource comments ← 댓글

그 다음 각각의 module에 가서 TypeOrmModule.forFeature([<Entity>])를 추가해주자.
안쓰면 Repository 못찾는다는 오류가 발생한다.

이에 맞춰 entity를 수정하자.
users.entity.ts@Entity({name: 'user'}) // 테이블의 기본 이름 설정
export class User {
@PrimaryGeneratedColumn()
uid: number;
@Column()
id: string;
@Column()
password: string;
@Column()
email: string;
@Column({default: 'default'})
nickname: string;
@CreateDateColumn()
createdAt: Date;
@OneToMany(
() => Essay,
essay => essay
)
essays: Essay[];
}
boards.entity.ts
@Entity("board")
export class Board {
@PrimaryGeneratedColumn()
uid: number;
@Column()
name: string;
@Column()
describe: string;
@CreateDateColumn()
createdAt: Date;
@ManyToOne(
() => User,
user => user.boards
)
owner: User;
@OneToMany(
() => Essay,
essay => essay.board
)
essays: Essay[];
}
essays.entity.ts
@Entity('essay')
export class Essay {
@PrimaryGeneratedColumn()
uid: number;
@Column()
title: string;
@Column({
length: 1000
})
content: string;
@CreateDateColumn()
createdAt: Date;
@UpdateDateColumn()
updatedAt: Date;
@Column({ default: 0 })
likeCount: number;
@Column({ default: 0 })
viewCount: number;
@ManyToOne(
() => User,
user => user.boards
)
owner: User;
@ManyToOne(
() => Board,
board => board.essays
)
board: Board;
@OneToMany(
() => Comment,
comment => comment.essay
)
comments: Comment[]
}
comments.entity.ts
@Entity('comment')
export class Comment {
@PrimaryGeneratedColumn()
cid: number;
@Column({default: ""})
content: string;
@CreateDateColumn()
createdAt: Date;
@UpdateDateColumn()
updatedAt: Date;
@ManyToOne(
() => Essay,
essay => essay.comments
)
essay: Essay;
@ManyToOne(
() => User,
user => user.comments
)
owner: User;
}
TypeOrmModule.forFeature을 import 하는 것을 잊지 말자.@Module({
imports: [
AuthModule,
UsersModule,
TypeOrmModule.forFeature([Board])
],
controllers: [BoardsController],
providers: [BoardsService],
exports: [
BoardsService // essay module에서 사용
]
})
export class BoardsModule {}
essays.module.ts
@Module({
imports: [
AuthModule,
BoardsModule,
UsersModule,
TypeOrmModule.forFeature([Essay])
],
controllers: [EssaysController],
providers: [EssaysService],
exports: [
EssaysService,
]
})
export class EssaysModule {}
comments.module.ts
@Module({
imports: [
UsersModule,
EssaysModule,
TypeOrmModule.forFeature([Comment])
],
controllers: [CommentsController],
providers: [CommentsService],
})
export class CommentsModule {}
여기는 입맛에 맞게 작성해주자.
코드가 너무 길어지므로 구현은 사용자가 알아서 하자.
중요한 부분은 아래와 같다. 이 부분만 잘 써주면 된다.
// 생성자
constructor(
// 레포지토리(데이터베이스) 연결
@InjectRepository(Comment)
private commentRepository: Repository<Comment>,
// 필요한 서비스들 추가
private essaysService: EssaysService,
private usersService: UsersService,
) {}
// 쿼리
const comments = await this.commentRepository.find({
where: { // 검색 조건은 어떻게 돼?
essay: essay,
},
order: { // 정렬 순서는 어떻게 돼?
createdAt: 'DESC',
},
skip: (page - 1) * this.pageSize, // 어디서부터 가져올거야?
take: this.pageSize, // 몇 개 가져올거야?
})
※ Repository에서 find를 할 때는 await 키워드를 빼먹지 말자. 기본이 Promise<Type>이라 엔티티의 값으로 넣을 때 Promise는 Type과 다릅니다 오류가 발생한다.

DBeaver로 확인을 해보았다.
원하는 entity 그대로 들어감을 볼 수 있다.
FastAPI보다 NestJS가 조금 더 편한 것 같다.
Guard, Interceptor를 자유자재로 사용할 수 있다는게 좋다는 점?