본문 바로가기
스터디/개발 몰입 과정

3주차 과제 - Nest.js로 REST API 만들기

by sepang 2021. 8. 27.

TypeORM 설정

{
    // ormconfig.json
  "type": "mysql",
  "host": "localhost",
  "port": "3306",
  "username": "root",
  "password": "525252",
  "database": "bulletin_board",
  "synchronize": false,
  "logging": true,
  "keepConnectionAlive": true,
  "entities": ["dist/**/*.entity{.ts,.js}"]
}

프로젝트의 최상위 경로에 위치 해당 설정은 app.module.ts에 TypeOrmModule을 import할 때 설정하기도 가능

src

app.module.ts

import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { UsersModule } from './users/users.module';
import { PostsModule } from './posts/posts.module';

@Module({
  imports: [TypeOrmModule.forRoot(), UsersModule, PostsModule],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}

typeORM을 import함. Users를 다루는 api와 Posts를 다루는 api를 분리하기 위해 모듈을 각각 설정함

src/users

users.dto.ts

export interface UsersDTO {
  id: number;
  name: string;
  email: string;
  password: string;
}

dto(데이터 이동 객체)를 통해 객체를 어떤 형식으로 받아올 것인지를 결정한다 해당 파일을 import하여 사용하면 위의 인터페이스와 맞지 않은 객체를 못 받게끔 할 수 있다.

users.entity.ts

import { Entity, Column, PrimaryGeneratedColumn, BeforeInsert } from 'typeorm';
import * as crypto from 'crypto';
@Entity('users')
export class UsersEntity {
  @PrimaryGeneratedColumn()
  id: number;

  @Column()
  name: string;

  @Column()
  email: string;

  @BeforeInsert()
  hashPassword() {
    this.password = crypto.createHmac('sha256', this.password).digest('hex');
  }
  @Column()
  password: string;
}

typeORM을 이용하여 테이블을 생성한다. 데코레이터를 이용해 여러 속성을 부여할 수 있다.

users.controller.ts

import { 
  Controller,
  Get,
  Post,
  Patch,
  Delete,
  Body,
  Param,
  HttpStatus,
} from '@nestjs/common';

import { UsersService } from './users.service';
import { UsersDTO } from './users.dto';

@Controller('users')
export class UsersController {
  constructor(private usersService: UsersService) {}

  @Get()
  async showAllUsers() {
    const users = await this.usersService.showAll();
    console.log(users);
    return {
      statusCode: HttpStatus.OK,
      message: "Users fetched successfully",
      users
    };
  }

  @Post()
  async createUsers(@Body() data: UsersDTO) {
    const user = await this.usersService.create(data);
    return {
      statusCode: HttpStatus.OK,
      message: 'User create successfully',
      user
    };
  }

  @Get(':id')
  async readUser(@Param('id') id: number){
    const data = await this.usersService.read(id);
    return {
      statusCode: HttpStatus.OK,
      message: 'User fetched successfully',
      data,
    };
  }

  @Patch(':id')
  async updateUser(@Param('id') id: number, @Body() data: Partial<UsersDTO>) {
    await this.usersService.update(id, data);
    return {
      statusCode: HttpStatus.OK,
      message: 'User updated successfully',
    };
  }

  @Delete(':id')
  async deleteUser(@Param('id') id: number) {
    await this.usersService.destroy(id);
    return{
      statusCode: HttpStatus.OK,
      Message: 'User deleted successfully',
    };
  }
}

본격적인 API가 구현이 되는 파일이다 데코레이터를 이용해 어떤 요청메소드에 어떤 파라미터를 받을지 정할 수 있다.

users.service.ts

import { Injectable, HttpStatus } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';

import { UsersEntity } from './users.entity';
import { UsersDTO } from './users.dto';

@Injectable()
export class UsersService {
  constructor(
    @InjectRepository(UsersEntity)
    private usersRepository: Repository<UsersEntity>,
  ){}

  async showAll() {
    return await this.usersRepository.find();
  }

  async create(data: UsersDTO) {
    const user = this.usersRepository.create(data);
    await this.usersRepository.save(data);
    return user;
  }

  async findByEmail(email: string): Promise<UsersDTO> {
    return await this.usersRepository.findOne({
      where: {
        email: email,
      },
    });
  }

  async read(id: number) {
    return await this.usersRepository.findOne({where: {id:id}});
  }

  async update(id: number, data: Partial<UsersDTO>) {
    await this.usersRepository.update({ id }, data);
    return await this.usersRepository.findOne({ id });
  }

  async destroy(id: number) {
    await this.usersRepository.delete({ id });
    return { deleted: true };
  }
}

controller를 구현할 때 필요한 함수들을 구현해놓은 파일이다. 확인할 수 있듯이 UsersDTO를 이용해 파라미터를 받을 때 형식을 제한할 수 있다.

Post에 대한 내용도 테이블의 속성만 다르지 거의 Users와 동일하므로 굳이 해당 내용을 추가할 필요는 없을 것 같다.

'스터디 > 개발 몰입 과정' 카테고리의 다른 글

4주차 개념 스터디  (0) 2021.08.27
3주차 개념 스터디  (0) 2021.08.24
2주차 과제 - 게시판 관련 REST API 만들어보기  (0) 2021.08.13
2주차 개념 스터디  (0) 2021.08.12
1주차 개념 스터디  (0) 2021.07.31

댓글