JS/Nest.js

[NestJS] 간단한 게시판 CRUD 구현하기

kth990303 2023. 1. 13. 17:25
반응형

 

이번 포스팅은 CRUD 경험이 한 번이라도 있다면 조금 지루할 수 있다. (nestjs든 spring이든 뭐든...)

 

 

최근 스프링과의 장단점 및 차이점을 비교해보기 위해 nodejs 진영의 백엔드 프레임워크인 NestJS를 공부중이다.

NestJS에 대한 소개, 설치 및 구축방법, 학습 동기는 아래 글을 참고하자.

https://kth990303.tistory.com/410

 

[NestJS] NestJS 설치 및 애플리케이션 구축해보기

NestJS는 nodejs (javascript) 진영에서 매우 유명한 백엔드 프레임워크이다. 공식 문서에서 nestjs는 typescript를 완전히 지원하며 OOP(Object Oriented Programming), FP(Functional Programming), FRP(Functional Reactive Programmin

kth990303.tistory.com

 

이번에는 간단한 게시글 CRUD를 기록해보려한다.

사실상 스프링으로 웹개발을 해보았다면 엄청 쉬운 포스팅일 수 있다.

 

참고로 이 강의(https://youtu.be/3JminDpCJNE)를 참고하면서 nestjs를 공부중이기 때문에 crud 부분은 내용이 거의 유사할 수밖에 없다. 

 

학습하면서 작성한 코드는 아래에서 확인할 수 있다.

https://github.com/kth990303/practice_nestjs

 

GitHub - kth990303/practice_nestjs: nestjs를 연습해보는 레포지토리

nestjs를 연습해보는 레포지토리. Contribute to kth990303/practice_nestjs development by creating an account on GitHub.

github.com


CRUD 구축

아래 기능들을 구현할 것이다.

  • createBoard(id: string, title: string): Board // 생성
  • getAllBoards(): Board[] // 조회
  • getBoardById(id: string): Board // 조회
  • updateBoardStatus(id: string, status: BoardStatus): Board // 수정
  • deleteBoard(id: string): void // 삭제

 

nestjs에서 typescript를 지원하다보니 파라미터 및 메서드 반환 객체에 타입을 붙여준다.

또한, api 명세 변경에 유연함을 갖추기 위해, 그리고 파라미터 수가 많아지는 상황을 대비함에 따라 DTO를 사용할 것이다. 

 

board.model.ts 코드

export interface Board {
    id: string,
    title: string,
    description: string,
    status: BoardStatus, // 공개글, 비공개글의 상태를 결정하는 필드
}

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

게시글에는 uuid 형식의 id를 가지고 있으며, 그 외에 title, description, status를 가진다.

status는 공개 여부를 나타내는 enum 형식이다.

 

참고로 DB와 연동은 아직 하지 않는다.

 

boards.controller.ts 코드 일부

@Get()
getAllBoards(): Board[] {
    return this.boardsService.getAllBoards();
}

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

@Get(), @Post() 와 같은 Http Method 데코레이터를 이용한다.

괄호 안에 별도로 명시해주지 않으면 디폴트로 '/' 가 매핑된다.

 

@Body를 이용하여 request body를 보내줄 수 있다.

@Body('id'), @Body('status')와 같이 이름을 명시해주는 것도 가능하지만, 우리는 DTO를 보내주고 있기 때문에 생략하였다.

 

CreateBoardDto

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

dto 코드는 위와 같다.

 

boards.controller.ts 코드 일부

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

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

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

스프링에서는 @PathVariable에 해당되는 인자를 중괄호로 감싸주지만, 여기서는 :를 이용한다.

 

또한, nestjs에서의 Http Response status code는 POST - 201, 그 외 GET, PATCH, DELETE 등 - 200 으로 고정된다. 

Furthermore, the response's status code is always 200 by default, except for POST requests which use 201. We can easily change this behavior by adding the @HttpCode(...) decorator at a handler-level (see Status codes).

 

그렇기 때문에 NO_CONTENT 와 같은 204 status code를 보내주고 싶은 경우는 @HttpCode 데코레이터를 사용해주었다.

 

컨트롤러 내 데코레이터

참고로 쿼리파람(query parameter)을 사용하고 싶으면 @Query 데코레이터를 사용하면 된다.

사용법은 @Param과 동일하다.


service에서는 비즈니스 로직을 작성하였다.

이 부분은 진짜 단순 js 문법에 해당되므로 빠르게 넘어가도록 하겠다.

 

boards.service.ts 코드 일부

@Injectable()
export class BoardsService {
    private boards: Board[] = [];

    getAllBoards(): Board[] {
        return this.boards;
    }

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

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

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

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

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

실행 결과

GET과 같은 단순 조회가 아닌 API 송수신 성공 확인 여부는 브라우저에서 확인이 어렵다.

따라서 postman으로 확인하였다. 

만약 postman이 없다면 아래 링크를 통해 무료로 다운받자.

https://www.postman.com/downloads/

 

Download Postman | Get Started for Free

Try Postman for free! Join 20 million developers who rely on Postman, the collaboration platform for API development. Create better APIs—faster.

www.postman.com

 

결과를 이제 postman으로 확인해보자.

 

GET, POST, DELETE 모두 의도한대로 잘 되며, status code 또한 제대로 나옴을 확인할 수 있다.

queryparam이 아닌 pathvariable 형태임을 주의하면서 postman을 잘 이용하도록 하자.


controller 내에서 더 다양한 데코레이터를 확인하고 싶다면 아래 공식문서를 참고하자.

https://docs.nestjs.com/controllers

 

Documentation | NestJS - A progressive Node.js framework

Nest is a framework for building efficient, scalable Node.js server-side applications. It uses progressive JavaScript, is built with TypeScript and combines elements of OOP (Object Oriented Progamming), FP (Functional Programming), and FRP (Functional Reac

docs.nestjs.com

 

 

반응형