오늘 한 일
새해 연휴동안 공연 예매 프로젝트를 완성시켰다(Nest.js + TypeORM). 그런데 테스트를 해보지 않고 생각으로만 만들어뒀던 코드들이라 오늘 코드들을 api client로 돌려보며 에러를 해결하는 하루를 보냈다. 테스트를 해보지 않고 생각대로만 만들었던 건데 기대했던 것보다 고칠 부분 없이 완성도 있게 만든 것 같아 뿌듯했다. 역시나, 언제나 그랬듯이(mongoose, sequelize,prisma에서도 그랬듯이) 초기 설정하는 부분이 조금 어려웠던 것 같다.
배운 부분
오류를 수정하며 배운 몇 가지에 대해 간략하게 적어보려고 한다.
TypeORM 메서드
원래 만들었던 코드에서는 특정한 id값이 주어졌을 때 그 id값의 row 하나를 가져오는 메서드로 find를 쓰고 있었다.
그런데 생각으로만 만든 코드였기 때문에 find라는 메서드가 배열을 반환하는지 객체를 반환하는지 몰랐다.
정리해보자면 find는 조건과 일치하는 모든 row를 배열의 형태로 가져오는 메서드였다.(findMany같은 느낌)
반대로 하나의 row값만을 가져오고 싶을 때는 findOne이나 findBy와 같은 메서드를 통해 객체 하나만을 가져올 수 있다.
private async verifyPerformanceById(id: number) {
const performance = await this.performanceRepository.findOneBy({ id });
if (_.isNil(performance)) {
throw new NotFoundException('존재하지 않는 공연입니다.');
}
return performance;
}
async login(email: string, password: string) {
const user = await this.userRepository.findOne({
select: ['id', 'email', 'password'],
where: { email },
});
if (_.isNil(user)) {
throw new UnauthorizedException('이메일을 확인해주세요.');
}
if (!(await compare(password, user.password))) {
throw new UnauthorizedException('비밀번호를 확인해주세요.');
}
const payload = { email, sub: user.id };
return {
access_token: this.jwtService.sign(payload),
};
}
*.service.ts 주의사항
service 파일에서는 repository를 사용해 직접 데이터베이스에 넣는 작업을 하는데 이 때 레퍼지토리를 주입하면서 entity에 정의된 파일을 가져와서 쓰게 된다. 따라서 쓰게 된다면 import를 꼭 해오고 써야 한다. entity에서 정의해 놓은 것들을 import하지 않고 사용하더라도 빨간색 밑줄(오류 보여주는 것)이 뜨지 않는다.
TypeOrmModule.forFeature()
TypeORM과 entity를 연결해 줄 때는 하나의 옵션이 추가적으로 필요한데 module을 정의해주는 부분에서 TypeOrmModule.forFeature([연결할 entity 이름])을 import해주면 된다.
//performance.module.ts
import { Module } from '@nestjs/common';
import { PerformanceController } from './performance.controller';
import { PerformanceService } from './performance.service';
import { TypeOrmModule } from '@nestjs/typeorm';
import { Performance } from './entities/performance.entity';
@Module({
imports: [TypeOrmModule.forFeature([Performance])],
controllers: [PerformanceController],
providers: [PerformanceService],
exports: [PerformanceService],
})
export class PerformanceModule {}
TypeORM에서 entity를 따로 설정하지 않아도 자동으로 불러와주는 옵션
app.module.ts에서 typeOrmModuleOptions를 설정해주는 부분이 있는데 여기서 autoLoadEntities: true를 추가하게 되면 entity를 따로 불러오지 않아도 자동으로 더해지게 된다.
const typeOrmModuleOptions = {
useFactory: async (
configService: ConfigService,
): Promise<TypeOrmModuleOptions> => ({
namingStrategy: new SnakeNamingStrategy(),
type: 'mysql',
username: configService.get('DB_USERNAME'),
password: configService.get('DB_PASSWORD'),
host: configService.get('DB_HOST'),
port: configService.get('DB_PORT'),
database: configService.get('DB_NAME'),
autoLoadEntities: true, //entity가 자동으로 더해지는 코드
synchronize: configService.get('DB_SYNC'),
logging: true,
}),
inject: [ConfigService],
};
혹은 entities: [__dirname + '/../**/*.entity.{js,ts}'] 를 넣어주는 것도 가능하다.
tpyeORM 메서드의 select
typeorm메서드의 select는 기본적으로 배열의 형태로 나열해서 원하는 컬럼을 가져오는데 이는 객체의 형태로 가져와도 무관하다.
const user = await this.userRepository.findOne({
select: ['id', 'email', 'password'],
where: { email },
});
async getAllPerformances(): Promise<Performance[]> {
const allPerformances = await this.performanceRepository.find({
select: {
name: true,
date: true,
time: true,
place: true,
seat: true,
image: true,
category: true,
},
});
return allPerformances;
}
'TIL' 카테고리의 다른 글
2024_01_05 TIL (1) | 2024.01.06 |
---|---|
2024_01_03 TIL (1) | 2024.01.04 |
2023_12_29 TIL (1) | 2023.12.30 |
2023_12_28 TIL (1) | 2023.12.29 |
2023_12_27 TIL (2) | 2023.12.28 |