gengminy
갱미니의 코딩일지
gengminy
전체 방문자
오늘
어제
  • 분류 전체보기 (61)
    • 🚀 프로젝트 (16)
      • 🎸 고스락 티켓 (4)
      • 🌞 내친소 (5)
      • 🥁 두둥 (7)
    • 📡 백엔드 (31)
      • 🌱 Spring Boot (13)
      • 🐱 Nest.js (10)
      • ⭐ Node.js (8)
    • 🏭 Infra (11)
      • ⚙ 준비를 위한 준비 (2)
      • 🥑 AWS (3)
      • 🐳 Docker (3)
      • ⚡ Github Actions (3)
    • 🌊 프론트엔드 (1)
      • 🌌 React.js (1)
    • 😎 주저리 (2)

블로그 메뉴

  • 💻Github
  • 📸Instagram
  • ✨Blog

공지사항

인기 글

태그

  • JWT
  • JSON
  • 도커
  • 슬랙알림
  • docker
  • 네스트
  • 스프링
  • oauth2
  • GithubActions
  • nestjs
  • OAuth
  • 스프링부트
  • AWS
  • nodejs
  • springboot
  • SlackAPI
  • Spring
  • nest
  • github
  • 깃헙액션

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
gengminy

갱미니의 코딩일지

[NestJs] 따라하면서 배우는 NestJs - 2 (기본적인 CRUD 수행)
📡 백엔드/🐱 Nest.js

[NestJs] 따라하면서 배우는 NestJs - 2 (기본적인 CRUD 수행)

2022. 7. 4. 16:41

 

 

✅ 서비스 의존성 주입 및 전체 READ

 

📝 ./boards/boards.service.ts

import { Injectable } from '@nestjs/common';

@Injectable()
export class BoardsService {
  //일단 로컬 메모리에 저장하는 방식으로
  private boards = [];

  getAllBoards() {
    return this.boards;
  }
}

 

📝 ./boards/boards.controller.ts

import { Controller, Get } from '@nestjs/common';
import { BoardsService } from './boards.service';

@Controller('boards')
export class BoardsController {
  constructor(private boardsService: BoardsService) {}

  @Get()
  getAllBoards() {
    return this.boardsService.getAllBoards();
  }
}

아직 간단한 예시라서 db는 사용하지 않고 로컬 메모리 (private boards)를 사용

의존성 주입 시킨 후에 @Get 핸들러를 등록했다

boards 디렉토리의 모듈에 등록된 애들은 {url}/boards 로 자동으로 라우팅이 되는 것 같다

 

 

 

✅ Board 모델 추가 및 eslint 충돌로 설정 변경

 

📝 ./boards/board.model.ts

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

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

여기서 CRLF와 LF 때문에 자꾸 eslint 와 prettier 충돌이 생겼다

vscode 에서 CRLF를 LF로 바꿔주면 괜찮아졌지만

근본적인 문제 해결을 위해 설정을 조금 바꿔주었다

 

 

📝 ./.eslintrc.js

module.exports = {
  parser: '@typescript-eslint/parser',
  parserOptions: {
    project: 'tsconfig.json',
    tsconfigRootDir : __dirname, 
    sourceType: 'module',
  },
  plugins: ['@typescript-eslint/eslint-plugin'],
  extends: [
    'plugin:@typescript-eslint/recommended',
    'plugin:prettier/recommended',
  ],
  root: true,
  env: {
    node: true,
    jest: true,
  },
  ignorePatterns: ['.eslintrc.js'],
  rules: {
    '@typescript-eslint/interface-name-prefix': 'off',
    '@typescript-eslint/explicit-function-return-type': 'off',
    '@typescript-eslint/explicit-module-boundary-types': 'off',
    '@typescript-eslint/no-explicit-any': 'off',
    "prettier/prettier": ["error", { "endOfLine": "auto" }], //이 부분 추가
  },
};

rules 에

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

이부분을 추가해주었다

 

 

📝 ./boards/boards.service.ts

import { Injectable } from '@nestjs/common';
import { Board } from './board.model';

@Injectable()
export class BoardsService {
  //일단 로컬 메모리에 저장하는 방식으로
  private boards: Board[] = [];

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

그리고 모델 생성으로 인해 자료형이 정해졌기 때문에

타입스크립트 문법에 따라 자료형을 명시해주어야 한다

 

 

✅ CREATE - Board 생성 로직

 

📝 ./boards/boards.service.ts

import { Injectable } from '@nestjs/common';
import { Board, BoardStatus } from './board.model';
import { v1 as uuid } from 'uuid';

@Injectable()
export class BoardsService {
    //일단 로컬 메모리에 저장하는 방식으로
    private boards: Board[] = [];

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

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

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

db를 사용하지 않아서 uuid 모듈을 추가해주었다

타입스크립트가 unique id가 있는지 없는지도 검사해주는 거 같은데 짱짱이네

 

 

 

✅ CREATE - 컨트롤러에 Post 핸들러 등록

 

📝 ./boards/boards.controller.ts

import { Body, Controller, Get, Post } from '@nestjs/common';
import { Board } from './board.model';
import { BoardsService } from './boards.service';

@Controller('boards')
export class BoardsController {
    constructor(private boardsService: BoardsService) {}

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

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

Controller에 Post 핸들러를 등록해준다

request body를 가져오는 방법도 데코레이터 @body를 사용하는 것이다

기본적으로 request body를 전체 가져오려면 @body() body 이고

특정 값만 가져오려면 @body('title') title 과 같이 사용한다

 

 

POSTMAN으로 테스트

 

 

✅ CREATE - DTO 도입


📝 ./boards/dto/create-board.dto.ts

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

데이터 전달의 안정성과 유효성 체크그리고 확장성을 위해

DTO (Data Transfer Object) 도입

해당 모듈의 dto 하위 디렉터리에 만들어준다

 

 

📝 ./boards/boards.controller.ts

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

 

📝 ./boards/boards.service.ts

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

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

수정 완료

 

 

✅ READ - id로 특정 board만 가져오기

 

📝 ./boards/boards.service.ts

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

 

📝 ./boards/boards.controller.ts

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

쿼리스트링의 변수는 @Param 으로 가져온다

마찬가지로 @Param() params: string[] 으로 전체 쿼리스트링 변수를 가져오거나

@Param('id') id: string 처럼 특정 변수만 가져올 수 있다

 

 

 

✅ DELETE - 특정 id의 board만 삭제

 

📝 ./boards/boards.service.ts

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

 

📝 ./boards/boards.controller.ts

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

아직 db를 사용하지 않으므로 내부 배열에서 filter 사용하는 방식으로 구현

이번에도 역시 쿼리스트링을 사용함

간단하다

 

 

 

✅ UPDATE - 특정 id의 board 상태 변경

 

📝 ./boards/boards.service.ts

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

 

📝 ./boards/boards.service.ts

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

@Patch 를 통해 update 메서드 실행

상태를 Public <-> Private 변경할 수 있도록 한다

 

 

아직까지는 매우 간단해보인다

화이팅

저작자표시 (새창열림)

'📡 백엔드 > 🐱 Nest.js' 카테고리의 다른 글

[NestJs] 따라하면서 배우는 NestJs - 5 (레포지토리 구현 및 DB 이용 CRUD)  (0) 2022.07.07
[NestJs] TypeORM 사용 시 RepositoryNotFoundError 해결하기  (0) 2022.07.06
[NestJs] 따라하면서 배우는 NestJs - 4 (Postgres, TypeORM 적용)  (0) 2022.07.05
[NestJs] 따라하면서 배우는 NestJs - 3 (pipe와 validation)  (0) 2022.07.04
[NestJs] 따라하면서 배우는 NestJs - 1 (기본 세팅 및 구조 파악)  (0) 2022.07.04
    '📡 백엔드/🐱 Nest.js' 카테고리의 다른 글
    • [NestJs] TypeORM 사용 시 RepositoryNotFoundError 해결하기
    • [NestJs] 따라하면서 배우는 NestJs - 4 (Postgres, TypeORM 적용)
    • [NestJs] 따라하면서 배우는 NestJs - 3 (pipe와 validation)
    • [NestJs] 따라하면서 배우는 NestJs - 1 (기본 세팅 및 구조 파악)
    gengminy
    gengminy
    코딩

    티스토리툴바