Nest.js + TypeORM 으로 연동후 CRUD 만들기 (쉬움)
요새 많은 스타트업들이 Nest.js 를 다루는 개발자를 많이 뽑는 것 같았다.
프론트개발자들이 서버를 개발할 때 새로운 언어를 공부해야 할 부담감도 적고, 성능도 좋다고 해서
어떤지 나도 한번 맛보기로 했다.
NestJS CLI 설치하기
NestJS 좋은점이 개발자가 좀 더 환경구축을 편리하게 할수 있도록 CLI를 제공 한다.
npm i -g @nestjs/cli
NestJS 프로젝트 구성하기
nest new nestjsProject
nest new 명령어는 새로운 프로젝트를 자동으로 구성하게 해준다.
따라서 nest new 프로젝트명 입력을 해준다.
NestJS 프로젝트 실행하기
cd nestjsProject
npm run start
방금 만들었던 프로젝트폴더에 들어가서 실행을 시켜준다.
curl http://localhost:3000
Hello World 라고 응답을 준다.
기본포트가 3000대 포트이다.
NestJS TypeORM 설정하기
[config > TypeORM.config.ts]
export const typeORMConfig: TypeOrmModuleOptions = {
type: 'mysql',
host: 'localhost',
port: 3306,
username: 'root',
password: '1111',
database: 'test',
entities: [BookEntity],
synchronize: true,
autoLoadEntities: true,
logging: true,
};
config 디렉토리를 만든 후 TypeORM.config.ts 파일을 만든후
위의 코드와 같이 연결할 데이터베이스의 정보를 입력해준다.
entities 는 TypeORM 관리대상에 들어갈 엔티티를 적는 공간이다.
synchronize 는 엔티티 와 데이터베이스 테이블을 자동으로 동기화할지 여부를 지정한다.
(현재 개발 및 테스트 상황이기에 true 로 설정하였다.)
logging 은 쿼리 로그를 보여준다. 예시로 JPA의 show_sql 기능과 유사하다.
entities 에서 에러가 날텐데 일단 냅두고 계속 진행하면된다.
필요한 것을 미리 적어두는 느낌이다.
NestJS CLI 이용하여 books 파일 생성하기
여기서 Nestjs CLI의 강력한 기능을 볼 수 있다.
nest g resource books
books 에 필요한 파일들을 전부 자동으로 생성해준다.
예를들어
BooksController, BooksService, BookEntity, Dto 등등 개발에 필요한 파일들을 생성해준다.
book.module.ts 파일을 열어 TypeORM이 사용할 엔티티 클래스를 지정한다.
@Module({
imports: [TypeOrmModule.forFeature([BookEntity])],
controllers: [BooksController],
providers: [BooksService],
})
export class BooksModule {}
그리고 사용할 controller 와 provider 를 지정한다.
BookEntity.ts 작성하기
@Entity({ name: 'book' })
export class BookEntity {
@PrimaryGeneratedColumn()
id: number;
@Column()
author: string;
@Column()
name: string;
@CreateDateColumn()
createdAt: Date;
@UpdateDateColumn()
updatedAt: Date;
@DeleteDateColumn()
deletedAt: Date;
}
소스코드를 보다보니 JPA 엔티티 설계할때와 유사한것 같았다.
books.service.ts 작성하기
@Injectable()
export class BooksService {
constructor(
@InjectRepository(BookEntity)
private bookEntityRepository: Repository<BookEntity>,
) {}
create(createBookDto: CreateBookDto) {
this.bookEntityRepository.save(createBookDto).then(() => throwIfEmpty());
return 'This action adds a new book';
}
findAll() {
return this.bookEntityRepository.find();
}
findOne(id: number) {
return this.bookEntityRepository.findOneBy({ id });
}
update(id: number, updateBookDto: UpdateBookDto) {
return this.bookEntityRepository.update(id, updateBookDto);
}
remove(id: number) {
return this.bookEntityRepository.delete(id);
}
}
@Injectable()
해당 클래스가 주입이 가능한 상태로 만들어주는 역할을 한다.
주입이 가능한 상태로만 만들어 놓을 뿐, 자동으로 주입이 되지 않는다.
그렇기 때문에, 위에 보면 provider에 book.server.ts 를 등록하였을텐데, 그 이유가 이러한 이유이다.
constructor(
@InjectRepository(BookEntity)
private bookEntityRepository: Repository<BookEntity>,
) {}
생성자 의존성 주입이다. (repository를 사용하기 위함)
@RequiredArgsConstructor
private final BookEntityRepository bookEntityRepository;
Java로 예시를 들면 이런느낌이다.
create(createBookDto: CreateBookDto) {
this.bookEntityRepository.save(createBookDto).then(() => throwIfEmpty());
return 'This action adds a new book';
}
findAll() {
return this.bookEntityRepository.find();
}
findOne(id: number) {
return this.bookEntityRepository.findOneBy({ id });
}
update(id: number, updateBookDto: UpdateBookDto) {
return this.bookEntityRepository.update(id, updateBookDto);
}
remove(id: number) {
return this.bookEntityRepository.delete(id);
}
나머지 소스코드는 다들 알다시피 CRUD 관련 서비스이다.
books.controller.ts 작성하기
@Controller('books')
export class BooksController {
constructor(private readonly booksService: BooksService) {}
@Post()
create(@Body() createBookDto: CreateBookDto) {
return this.booksService.create(createBookDto);
}
@Get()
findAll() {
return this.booksService.findAll();
}
@Get(':id')
findOne(@Param('id') id: string) {
return this.booksService.findOne(+id);
}
@Patch(':id')
update(@Param('id') id: string, @Body() updateBookDto: UpdateBookDto) {
return this.booksService.update(+id, updateBookDto);
}
@Delete(':id')
remove(@Param('id') id: string) {
return this.booksService.remove(+id);
}
}
Spring 이랑 완전 비슷한 느낌이 든다.
Java 개발자인 나도, 쉽게 적용하고 읽힐만큼 강력한 가독성을 지니고 있는 것 같다.
Postman 으로 api 통신 테스트
Create.
데이터 추가 후 로그를 확인하면, SQL 쿼리가 자동으로 날라간다.
Read.
Update.
Delete.
다시 조회를 해보면 아래 그림처럼 데이터가 정상적으로 삭제되어 비어있게 된다.
느낀점
요새 스타트업 회사에서 Express.js , Nest.js 등 많은 사람들을 채용하고 있는 것 같다.
물론 깊게 다뤄보진 않았지만, 자바스크립트 지식만 있으면 누구나 쉽게 할수 있을 것같다.
워낙 개발자가 개발에만 집중할 수 있도록 기본적인 편리한 인터페이스 기능들이 많이 탑재되어 있고,
강력한 가독성도 지니고 있어, 러닝 커브가 쉬울 것으로 예상된다.(물론 깊게들어가면 갈수록 알아야할 것이 많다.)