본문 바로가기

Backend/NestJS

[NestJS Overview] Service.ts(서비스 파일, 반환 클래스, 예외처리)

728x90
NestJS 서비스 파일에 대한 기록이다.

개요

이번 기록에서는 비즈니스 로직의 역할을 맡는 서비스 파일에 대한 기록이다.

 

비즈니스 로직을 어떻게 작성할지, 반환하는 객체에 대한 클래스 생성, 컨트롤 파일에서 서비스 파일을 사용하는 법

마지막으로 client 요청에 대한 예외처리를 다룰 예정이다.

 

Service.ts

지난번 기록에 이어 todos API를 계속해서 만들어보자.

 

[NestJS] controllers 파일(참조 순서, Routing)

NestJS의 controllers 파일에 대한 공부 기록이다. Controllers 기능 Controllers는 client의 request를 받고, response를 제공하는 역할을 한다. client의 요청 url router를 분리하는 기능도 한다. 위의 사진에서 볼 수

choi-records.tistory.com

저번 기록에서는 todos controllers.ts 파일에 대해 기록했었다.

 

이번에는 서비스 파일을 생성해보자.

$nest generate service
$nest g s

위의 명령어로 서비스 파일을 생성해준다.

이름은 이전 기록과 동일하게 todos로 해준다.

 

명령어를 입력하면, service.ts 파일이 생성되고,

todos.module.ts 파일의 providers에 해당 Service가 추가된 것을 볼 수 있다.

service파일에서는 비즈니스 로직을 처리한다.

따라서 DB와의 연동을 통해 server resource를 관리해야 하지만

초기 기록에서는 Nest의 전체적인 구조를 그리기 위함이므로 가짜 DB를 만들어서 진행하도록 하자.

export class TodosService {
    private todos=[];
}

todos에 대한 타입 정의가 안 되어있다.

entity파일을 생성해서 todo에 대한 타입 정의를 해주자.

entity
DB가 어떻게 생겼는지 알려주는 타입 정의를 해주는 파일
//todos.entitiy.ts
export class todo {
  id: number;
  action: string;
}

간단하게 todo의 타입을 지정해주고, 위의 service 파일을 수정해준다.

import { Injectable } from '@nestjs/common';
import { todo } from './entities/todos.entity';
@Injectable()
export class TodosService {
  private todos: todo[] = [];
}

이제 저번 기록에서 controller에서 구현한 로직을 직접 구현해보자.

import { Injectable } from '@nestjs/common';
import { todo } from './entities/todos.entity';

@Injectable()
export class TodosService {
  private todos: todo[] = [];

  getAll() {
    return this.todos;
  }
  getOne(id: string) {
    return this.todos.find((toDo) => toDo.id === +id);
  }

  deleteOne(id: string): boolean {
    this.todos = this.todos.filter((movie) => movie.id !== +id);
    return true;
  }

  create(todoData) {
    this.todos.push({
      id: this.todos.length + 1,
      ...todoData,
    });
  }

  update(id: string, updateData) {
    const todo = this.getOne(id);
    this.deleteOne(id);
    this.todos.push({
      ...todo,
      ...updateData,
    });
  }
}

위와 같이 구현해줬다.

 

이제 해당 서비스 파일의 로직을 컨트롤 파일에서 이용해보자.

 

Service~Controller

Service 파일에서 Controller를 가져오는 것은 쉽다.

여기서 Dependency Injection이라는 개념이 등장한다.

Dependency Injection

module 파일의 providers에 service 클래스를 전달해주면,
Controller파일에서 service 클래스로 타입만 지정해줘도 로직을 사용할 수 있도록 해준다.

 

코드로 보면 이해가 쉽다.

constructor(private readonly todosService: TodosService) {}

클래스 내부에 위와 같은 생성자를 생성해주고, 타입을 해당 서비스 클래스로 지정해주면

서비스 파일에서 작성한 로직을 사용할 수 있는 것이다.

 

이제 서비스 파일에서 작성한 로직을 사용해 Controller 파일을 수정해보자.

@Controller('todos')
export class TodosController {
  constructor(private readonly todosService: TodosService) {}
  @Get()
  getAll() {
    return this.todosService.getAll();
  }

  @Get('/:id')
  getOne(@Param('id') id: string): todo {
    return this.todosService.getOne(id);
  }

  @Post()
  create(@Body() todoData) {
    return this.todosService.create(todoData);
  }

  @Delete('/:id')
  remove(@Param('id') id: string) {
    return this.todosService.deleteOne(id);
  }

  @Patch('/:id')
  patch(@Param('id') id: string, @Body() updateData) {
    return this.todosService.update(id, updateData);
  }
}

위와 같이 API를 생성했다.

이제 postman으로 테스트해보자.

 

post, getAll 요청 성공
delete 요청 성공
update 요청 성공

예외 처리

client에게 오류를 보내주는 방법에 대해 알아보자.

 

client가 부적절한 요청을 보낸다면,

이런 요청에 대해서 controller에서 client의 요청에 대한 타입을 지정해줌으로써

에러를 보여줄 수도 있지만 이 방법은 다음 기록에서 다루기로 하자.

 

이번 기록에서는 서비스 파일에서 예외 처리하는 방법에 대해 기록하려고 한다.

 

client가 잘못된 URI로 접속했다고 가정해보자.

이 경우엔 잘못된 요청이 아니므로, 서비스 파일에서 예외를 처리해줘야 한다. 

 

위의 getOne 메서드를 수정해보자.

  getOne(id: string) {
    const toDo = this.todos.find((toDo) => toDo.id === +id);
    if (!toDo) {
      return new NotFoundException(`wrong id : ${id}`);
    }
    return toDo;
  }

위와 같이 수정해주면, client의 잘못된 접속에 예외를 처리해줄 수 있다.

정상적으로 에러 메세지가 전달된 것을 확인할 수 있다.


출처

 

NestJS로 API 만들기 – 노마드 코더 Nomad Coders

Enterprise Server Side Applications

nomadcoders.co

마치며

백엔드도, NestJS도 처음이라 부족함이 많은 글입니다.

잘못된 정보에 대한 피드백은 환영입니다.

감사합니다.

728x90