따라하면서 배우는 NestJS #2 - NestJS로 게시판 CRUD 기능 사용하기

Jina Kim·2022년 10월 11일
0

NestJS

목록 보기
3/6
post-thumbnail
post-custom-banner

출처: 따라하면서 배우는 NestJS https://www.youtube.com/watch?v=3JminDpCJNE

📖 CRUD 중 Read 사용하기

게시물을 불러오는 read 펑션을 만들어보자.

service 코드

// boards.service.ts
private boards = [];

getAllBoards() {
  return this.boards;
}

위와 같이 getAllBoards 라는 펑션을 정의한다.
말그대로 boards라는 로컬메모리에 저장된 값을 가져오는 메소드.

controller 코드

// boards.controller.ts
@Get()
getAllBoard() {
  return this.boardsService.getAllBoards();
}


그리고 GET 방식으로 getAllBoard() 펑션 내에서
boardService의 getAllBoards() 메소드를 호출.

@Controller('boards')로 route가 선언되어있기 때문에
http://localhost:3000/boards 을 웹페이지에 쳐보면

service내에 선언한 boards 값이 보인다.

Model

필요한 데이터를 정의해준다.
ex) 게시물의 제목, 내용, 작성자 등

board model 생성

board.model.ts 파일을 생성한다.

export interface Board {
  id: string;
  title: string;
  description: string;
  status: BoardStatus;
}

export enum BoardStatus {
  PUBLIC = 'PUBLIC',
  PRIVATE = 'PRIVATE',
}

위와 같이 적어준다.

💡eol error

처음에 end of line에 자꾸 빨간줄이 나타났다.

에러문구는 delete 'cr' 이었다.
찾아보니 eol 에러여서 .eslintrc파일의 rules에 아래와 같이 적어주면 간단히 해결된다.

'prettier/prettier': [
    'error',
    {
      'endOfLine': 'auto',
    }
  ]

service와 controller에 board 타입 선언

service code

controller code

: type

자료형을 선언해줄 때는 위와 같이 semicolon 뒤에 type을 써주면 된다.
ex) getAllBoard(): Board[] // 이거는 Board의 배열이라 []을 써준것.

🔨 CRUD 중 Create 사용하기

게시물을 생성하는 create 펑션을 만들어보자.

service 코드

  createBoard(title: string, description: string): Board {
    const board: Board = {
      id: uuid(),
      title,
      description,
      status: BoardStatus.PUBLIC,
    };

    this.boards.push(board);
    return board;
  }

uuid는 유니크한 ID를 생성해주는 모듈이다.

$ npm install uuid --save

위의 cmd로 uuid 모듈을 설치해준다.

import { v1 as uuid } from 'uuid';

상단에 import 해줘야 service 코드가 작동한다.

리턴값은 : Board 이다.

controller 코드

  @Post()
  createBoard(
    @Body('title') title: string,
    @Body('description') description: string,
  ): Board {
    return this.boardsService.createBoard(title, description);
  }

Post 방식으로 호출하는거라 Postman 프로그램을 써야한다.

@Body

바디 안의 request 인자들의 값을 가져올 수 있다.
ex) @Body('title') // title라는 값을 body 인자에서 가져온다.

Postman으로 호출하기

Post로 호출하고 url은 http://localhost:3000/boards

{
    "title": "board 1",
    "description": "description 1"
}

를 body에 JSON 형태로 붙여서 보내면

{
    "id": "c467e9d0-4927-11ed-97a2-fd21f4aece17",
    "title": "board 1",
    "description": "description 1",
    "status": "PUBLIC"
}

위와 같이 Board 타입으로 생성된 board가 리턴된다.
id는 uuid 모듈을 써서 랜덤값의 유니크한 id가 만들어졌다.


2개의 board를 생성했고, Get으로 http://localhost:3000/boards를 호출하니

이렇게 생성된 boards가 리턴된다.

DTO(Data Transfer Object)

데이터 유효성 체크에 효율적이다.
인자값의 이름을 변경할 때, DTO를 이용하면 안정적이고 효율적으로 변경이 가능하다.

DTO를 만들 때는 class를 이용하는게 좋음

createBoard DTO 코드

boards > dto(새로 만들기) > create-board.dto.ts(새로 만들기)

export class CreateBoardDto {
  title: string;
  description: string;
}

createBoard controller 코드

  @Post()
  createBoard(@Body() createBoardDto: CreateBoardDto): Board {
    return this.boardsService.createBoard(createBoardDto);
  }

이번에는 DTO 타입을 추가해서 createBoard 펑션을 변경해봤다.
createBoardDto에 title, description 등 Board의 프로퍼티가 담겨져 있으니
나중에 board에 다양한 필드가 추가되어도, createBorad 펑션 자체는 변경하지 않아도 된다.

service나 dto 파일만 변경하면 한번에 처리됨!

createBoard service 코드

  createBoard(createBoardDto: CreateBoardDto): Board {
    const { title, description } = createBoardDto;
    
    const board: Board = {
      id: uuid(),
      title,
      description,
      status: BoardStatus.PUBLIC,
    };

    this.boards.push(board);
    return board;
  }
}

import { CreateBoardDto } from './dto/create-board.dto';

dto파일의 CreateBoardDto class를 import해준다.

const { title, description } = createBoardDto; // DTO를 사용하면 title과 description의 타입을 한번에 정의해줄 수 있다.

📑 Read 펑션에 Param 사용하기

Id로 특정 게시물을 가져오는 펑션을 만들어보자.

service 코드

  getBoardById(id: string): Board {
    return this.boards.find((board) => board.id === id);
  }

id 라는 인자를 받은 후, boards 배열에서 해당 id와 일치하는 board 리턴

controller 코드

  @Get('/:id')
  getBoardById(@Param('id') id: string): Board {
    return this.boardsService.getBoardById(id);
  }

parameter인 받을 때는 :id와 같이 url 지정해주고

@Param을 이용한다.

@Param

get으로 호출한 parameter 값을 가져올 수 있다.
ex) @Param('id') // id 값을 url에서 가져온다.

결과값

http://localhost:3000/boards/dc362790-493e-11ed-a42d-6b520a72c5a4
이렇게 boards/:id를 호출하니 아래와 같이 해당하는 board가 나온다.

궁금해서 query param에 id=### 로도 넣어봤다.

응 안됩니다~
신기하게도 에러는 안나네여? ㅎㅅㅎ

🗑 CRUD 중 Delete 사용하기

id로 특정 게시물을 지워보자.

service 코드

  deleteBoard(id: string): void {
    this.boards = this.boards.filter((board) => board.id !== id);
  }

board.id가 인자 id랑 같지 않다면 남긴다. id가 같을 때만 삭제하는 로직

controller 코드

  @Delete('/:id')
  deleteBoard(@Param('id') id: string): void {
    this.boardsService.deleteBoard(id);
  }

@Delete로 호출하고 param은 id이다.
return값 따로 없이 service의 deleteBoard(id) 펑션만 호출한다.

결과값


: deleteBoard 호출 전 boards 배열 / : deleteBoard 호출 후 boards 배열

🎰 CRUD 중 Update 사용하기

특정 id 게시물의 status를 변경해보자.

service 코드

  updateBoardStatus(id: string, status: BoardStatus): Board {
    const board = this.getBoardById(id);
    board.status = status;
    return board;
  }

getBoardById(id)로 특정 게시물을 가져온다.

controller 코드

  @Patch('/:id/status')
  updateBoardStatus(
    @Param('id') id: string,
    @Body('status') status: BoardStatus,
  ) {
    return this.boardsService.updateBoardStatus(id, status);
  }

update 호출은 PUT으로 했던것 같은데, 여기서는 @Patch를 썼다.
id는 @Param으로 부르고, status는 @Body로 넘겨준다.

결과값


url은 boards/:id/status PATCH로 호출했고
body에는 status:"PRIVATE" 값을 넘겨주었다.

예쁘게 상태값 업데이트 완!

profile
Hello, World!
post-custom-banner

0개의 댓글