NestJS와 TypeORM으로 간단하게 CRUD API 만들기
NestJS와 TypeORM으로 간단하게 CRUD API 만들기
소개
NestJS는 Node.js를 위한 프로그레시브 웹 프레임워크로, 최신의 자바스크립트 기능을 활용하여 강력한 서버사이드 애플리케이션을 구축할 수 있게 도와줍니다. TypeORM은 TypeScript와 함께 사용하기 좋은 ORM(Object Relational Mapper)으로, 쉽게 데이터베이스와 상호작용할 수 있게 해줍니다. 이 글에서는 NestJS와 TypeORM을 사용해서 간단한 CRUD(Create, Read, Update, Delete) API를 만드는 방법을 알아보겠습니다.
준비물
- Node.js와 npm이 설치되어 있어야 합니다.
- NestJS CLI가 설치되어 있어야 합니다.
npm install -g @nestjs/cli
프로젝트 설정
NestJS 프로젝트를 생성하고 TypeORM을 설정하는 단계부터 시작하겠습니다.
프로젝트 생성
먼저, NestJS 프로젝트를 생성합니다.
shnest new crud-api cd crud-api
생성된 프로젝트로 이동한 후, 필요한 패키지들을 설치합니다.
shnpm install --save @nestjs/typeorm typeorm mysql2
여기서는 MySQL을 사용합니다. 다른 데이터베이스를 사용하려면 패키지를 변경하면 됩니다.
환경 설정
루트 디렉토리에 .env
파일을 생성하고 데이터베이스 연결 정보를 설정합니다.
DB_HOST=localhost
DB_PORT=3306
DB_USERNAME=root
DB_PASSWORD=password
DB_DATABASE=testdb
src/app.module.ts
파일을 수정하여 TypeORM을 설정합니다.
typescriptimport { Module } from '@nestjs/common'; import { TypeOrmModule } from '@nestjs/typeorm'; import { ConfigModule } from '@nestjs/config'; @Module({ imports: [ ConfigModule.forRoot({ isGlobal: true, }), TypeOrmModule.forRoot({ type: 'mysql', host: process.env.DB_HOST, port: parseInt(process.env.DB_PORT, 10), username: process.env.DB_USERNAME, password: process.env.DB_PASSWORD, database: process.env.DB_DATABASE, entities: [__dirname + '/**/*.entity{.ts,.js}'], synchronize: true, }), // 다른 모듈들을 여기에 추가할 수 있습니다. ], }) export class AppModule {}
엔티티 생성
간단한 Item
엔티티를 만듭니다. 이 엔티티는 데이터베이스 테이블과 매핑되며, CRUD 연산을 수행할 대상이 됩니다.
typescriptimport { Entity, Column, PrimaryGeneratedColumn } from 'typeorm'; @Entity() export class Item { @PrimaryGeneratedColumn() id: number; @Column() name: string; @Column('text') description: string; }
서비스와 컨트롤러 작성
서비스와 컨트롤러를 작성하여 CRUD API를 구현합니다.
서비스
서비스 클래스는 비즈니스 로직을 담당합니다. src/item/item.service.ts
파일을 생성하여 다음과 같이 작성합니다.
typescriptimport { Injectable } from '@nestjs/common'; import { InjectRepository } from '@nestjs/typeorm'; import { Repository } from 'typeorm'; import { Item } from './item.entity'; @Injectable() export class ItemService { constructor( @InjectRepository(Item) private readonly itemRepository: Repository<Item>, ) {} async findAll(): Promise<Item[]> { return this.itemRepository.find(); } async findOne(id: number): Promise<Item> { return this.itemRepository.findOne(id); } async create(item: Item): Promise<Item> { return this.itemRepository.save(item); } async update(id: number, item: Item): Promise<void> { await this.itemRepository.update(id, item); } async remove(id: number): Promise<void> { await this.itemRepository.delete(id); } }
컨트롤러
컨트롤러 클래스는 HTTP 요청을 처리하고 서비스 클래스를 호출하여 응답을 반환합니다. src/item/item.controller.ts
파일을 생성하여 다음과 같이 작성합니다.
typescriptimport { Controller, Get, Post, Body, Param, Delete, Put } from '@nestjs/common'; import { ItemService } from './item.service'; import { Item } from './item.entity'; @Controller('items') export class ItemController { constructor(private readonly itemService: ItemService) {} @Get() findAll(): Promise<Item[]> { return this.itemService.findAll(); } @Get(':id') findOne(@Param('id') id: number): Promise<Item> { return this.itemService.findOne(id); } @Post() create(@Body() item: Item): Promise<Item> { return this.itemService.create(item); } @Put(':id') update(@Param('id') id: number, @Body() item: Item): Promise<void> { return this.itemService.update(id, item); } @Delete(':id') remove(@Param('id') id: number): Promise<void> { return this.itemService.remove(id); } }
모듈 등록
Item
모듈을 등록하여 완성합니다. src/item/item.module.ts
파일을 생성하여 다음과 같이 작성합니다.
typescriptimport { Module } from '@nestjs/common'; import { TypeOrmModule } from '@nestjs/typeorm'; import { Item } from './item.entity'; import { ItemService } from './item.service'; import { ItemController } from './item.controller'; @Module({ imports: [TypeOrmModule.forFeature([Item])], providers: [ItemService], controllers: [ItemController], }) export class ItemModule {}
이제 AppModule
에 ItemModule
을 등록합니다. src/app.module.ts
파일을 다음과 같이 수정합니다.
typescriptimport { Module } from '@nestjs/common'; import { TypeOrmModule } from '@nestjs/typeorm'; import { ConfigModule } from '@nestjs/config'; import { ItemModule } from './item/item.module'; @Module({ imports: [ ConfigModule.forRoot({ isGlobal: true, }), TypeOrmModule.forRoot({ type: 'mysql', host: process.env.DB_HOST, port: parseInt(process.env.DB_PORT, 10), username: process.env.DB_USERNAME, password: process.env.DB_PASSWORD, database: process.env.DB_DATABASE, entities: [__dirname + '/**/*.entity{.ts,.js}'], synchronize: true, }), ItemModule, ], }) export class AppModule {}
결론
이제 NestJS와 TypeORM을 사용하여 간단한 CRUD API를 구현하는 방법을 배웠습니다. 이 애플리케이션은 기본적인 CRUD 연산을 수행할 수 있으며, 이를 바탕으로 더 복잡한 비즈니스 로직과 다양한 기능을 추가해 나갈 수 있습니다. 다음 단계로는 인증, 권한 부여, 테스트 등 더 고급 주제들을 배우고 프로젝트에 적용해 보세요.