전체/NestJS

NestJs 토이 프로젝트 구성해보기 - 1

effortDev 2023. 7. 16. 18:23

NestJS는 백엔드 서버 사이드 애플리케이션을 구축하기 위한 프레임워크이다.

고양이 그림이 귀여워서 공부해보았다.

 

 

 

1. nestjs/cli 를 전역으로 설치해준다.

 

1
2
3
# nest 프로젝트 설치
$ npm i -g @nestjs/cli
$ nest new nestjs-study
cs

 

2. 적절한 위치에서 nestjs 프로젝트를 생성해준다.

 

3. vsc 를 실행하면 다음과 같은 구조가 보일것이다.

NestJS는 모듈, 서비스, 컨트롤러라는 개념을 사용해 코드를 구조화한다.

 

4. 서버를 실행하면 Hello World 가 나오게 된다.

5. 모듈, 서비스, 컨트롤러라는 개념을 적용해 확장 구현해보자.

 

아래 cmd를 이용해 task subject에 대한 service, controller, module을 생성해준다.

 

 

1
2
3
4
# controller, service, module 생성
$ nest generate controller task
$ nest generate service task
$ nest generate module task
cs

src 하위로 디렉토리가 생성된다. 

 

6. TypeORM을 사용하여 Google Cloud SQL의 MySQL 데이터베이스에 연결하기

 

1
2
3
4
5
6
7
8
9
10
11
# type orm mysql 설치
$ npm install --save @nestjs/typeorm typeorm mysql
 
# 환경변수 설정파일 
$ npm install dotenv
 
# config env파일 불러오기 위한 설치
$ npm install @nestjs/config
 
# swagger 설치
$ npm install --save @nestjs/swagger swagger-ui-express
cs

 

필요한 노드 패키지를 설치해준다.

.env 파일에 민감한 정보를 작성해주고 저장한다.

 

 

6-1. app.module.ts 파일을 수정해준다.

import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { TaskModule } from './task/task.module';
import { ConfigModule } from '@nestjs/config';

@Module({
  imports: [
    ConfigModule.forRoot({
      isGlobal: true, // makes the config global
      envFilePath: '.env', // point to .env in root directory
    }),
    TypeOrmModule.forRoot({
      type: 'mysql',
      host: process.env.DB_HOST,
      port: +process.env.DB_PORT,
      username: process.env.DB_USERNAME,
      password: process.env.DB_PASSWORD,
      database: process.env.DB_DATABASE,
      entities: [__dirname + '/**/*.entity{.ts,.js}'],
      synchronize: true,
      extra: process.env.INSTANCE_CONNECTION_NAME && process.env.NODE_ENV === 'dev' 
      ? { socketPath: `/cloudsql/${process.env.INSTANCE_CONNECTION_NAME}` } 
      : undefined,
    }),
    TaskModule,
  ],
})
export class AppModule {}

 

6-2. task.entity.ts 파일을 만든다.

import { Entity, PrimaryGeneratedColumn, Column } from 'typeorm';

@Entity('tasks') // Specifies the name of the table in the database
export class Task {
  @PrimaryGeneratedColumn()
  id: number;

  @Column()
  title: string;

  @Column()
  description: string;
}

 

6-3. task.controller.ts 파일을 수정해준다.

import { Controller, Get, Post, Body } from '@nestjs/common';
import { TaskService } from './task.service';
import { Task } from './task.entity';
import { ApiOperation, ApiResponse, ApiTags } from '@nestjs/swagger';

@ApiTags('task API')
@Controller('tasks')
export class TaskController {
  constructor(private taskService: TaskService) {}

  @ApiOperation({ summary: 'Retrieve a list of task.' })
  @ApiResponse({ status: 200, description: 'List of task.' })
  @Get()
  findAll(): Promise<Task[]> {
    return this.taskService.findAll();
  }

  @ApiOperation({ summary: 'Create an task.' })
  @ApiResponse({ status: 201, description: 'The task has been successfully created.' })
  @Post()
  create(@Body() task: Task): Promise<Task> {
    return this.taskService.create(task);
  }
}

 

6-4. task.service.ts 파일을 수정해준다.

import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { Task } from './task.entity';

@Injectable()
export class TaskService {
  constructor(
    @InjectRepository(Task)
    private taskRepository: Repository<Task>,
  ) {}

  findAll(): Promise<Task[]> {
    return this.taskRepository.find();
  }

  create(task: Task): Promise<Task> {
    return this.taskRepository.save(task);
  }
}

 

6-5. task.module.ts 파일을 수정해준다.

import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { TaskController } from './task.controller';
import { TaskService } from './task.service';
import { Task } from './task.entity';

@Module({
  imports: [TypeOrmModule.forFeature([Task])],
  controllers: [TaskController],
  providers: [TaskService],
})
export class TaskModule {}

 

6-6 main.ts 파일을 수정해준다.

import { NestFactory } from '@nestjs/core';
import { SwaggerModule, DocumentBuilder } from '@nestjs/swagger';
import { AppModule } from './app.module';
import { INestApplication } from '@nestjs/common';

export function setupSwagger(app: INestApplication) {
  const options = new DocumentBuilder()
    .setTitle('NestJS Swagger')
    .setDescription('API documentation')
    .setVersion('1.0')
    .addTag('NestJS API LIST')
    .build();
  
  const document = SwaggerModule.createDocument(app, options);
  SwaggerModule.setup('api-docs', app, document);
}

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  setupSwagger(app);
  await app.listen(3000);
}
bootstrap();

 

구조는 아래와 같을 것이다.

서버를 켜고 DB접속이 정상적이라면

아래와 같은 결과를 확인할수 있다.

 

http://localhost:3000/api-docs#/ 로 접속시

swagger도 정상적으로 접근되는것을 확인할수 있다.

 

 

테스트는 Talend API Tester 크롬 확장프로그램을 사용하겠다.

 

GET 데이터 조회

 

POST 데이터 조회

 

데이터의 영속성이 보장되니 db tool (dbeaver) 을 이용하여 데이터를 확인할 수 있다.

 

다음편은 Google Auth Login을 활용해 보겠다.