NestJS Service란? (ft. Providers)

Olivia·2023년 8월 8일
0

[NestJS]

목록 보기
4/12
post-thumbnail

NestJS에서 Service란?

Service 안에서는 데이터베이스 관련된 로직을 처리한다.
데이터베이스에서 데이터를 생성, 조회, 업데이트, 삭제하거나 데이터 유효성을 체크하는 등의 작업을 수행한다.

이 Service를 사용할 때는, @Injectable로 감싸져서 모듈에 제공되며, 이 Service는 어플리케이션 전체에서 사용될 수 있다.
Injectable의 의미는 주입할 수 있다는 의미다.
그렇기 때문에, A controller, B controller, C controller ... 등에서 해당 service를 주입해서 사용할 수 있는 것이다.

@Injectable()
export class HiService{
	getHi(): string {
    	return `Hello World!`;
    }
}

위의 Service는 Controller에서 다음과 같이 사용할 수 있다.

@Get()
getHi(): string{
	return this.hiService.getHi();
}

Controller에서 this.hiService.getHi()를 사용함으로써 Service에 정희한 getHi메소드를 Controller에 주입하여 사용할 수 있다.

예 #02 - 참고

import {UsersService} from './users.service';
import {User} from './users.model';


@Controller('user')
export class UsersController {
	constructor(private usersService: UsersService){}
  
  @Get('/:id)
      getUserById(@Param('id') id:string):User{
  		return this.usersService.getUserById(id);	
  	  }
}

위의 코드는 Controller와 Service 사이의 의존성 주입을 보여주고 있다.

  • UserController : NestJS에서 User Controller 클래스를 정의하고 있다.
    이 Controller의 경우@Controller('user')로 엔드포인트가 /user와 관련된 요청일 경우 처리되는 컨트롤러다.

  • Constructor : UsersController 안에 생성자로 UsersService를 주입받는다.
    이 Constructor를 통해 Controller가 해당 Service를 사용할 수 있게 되는 것이다.

  • @Get('/:id') :/user/:id경로로 HTTP GET 요청이 들어올때 처리하게 된다.
    파라미터로 id를 가져와 변수에 할당한다.

  • getUserById : getUserById 메서드가 usersService안에 있는 getUserById 메서드를 호출해서 id에 따른 특정 글을 가져온다.

Service 생성 방법

NestJS에서 Service는 명령어로 생성한다.

  1. Service 생성 명령어 입력

    nest g service 이름 --no-spec or nest g service 이름

터미널에 위의 명령어를 입력하면 생성된다.
여기서 각각 의미하는 걸 알아보자면,

  • nest : nest Cli를 사용해서
  • g : generate 만든다.
  • service : service를 만든다
  • 이름 : 해당 이름을 가진
  • --no-spec : 테스트하는 부분을 생성하지 않는다. (test 부분을 생성할 경우 생략해도 된다)
    nest Cli를 이용해서 + 만든다 + service를 + [이름] 이름으로 된

2. service가 만들어지는 순서

1️⃣ 명령어를 통해
2️⃣ 해당 폴더 안에 service가 생성되면
3️⃣ 자동적으로 해당 폴더.module.ts안에 providers에다가 자동으로 업데이트가 된다.

service 파일

@Injectable 데코레이터가 있다. 이를 통해 다른 컴포넌트에서 해당 service를 주입할 수 있게 된다.

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

@Injectable()
export class UsersService {}
module 파일

터미널에서 cli로 service를 생성하면 아래와 같이 module의 Providers 부분에 자동으로 해당 service가 추가된다.

import { Module } from '@nestjs/common';
import { UsersController } from './users.controller';
import {UsersService} from './users.service';

@Module({
  controllers: [UsersController],
  providers: [UsersService],
})
export class UsersModule {}

이 service에서는 Controller에서보다 조금 더 복잡한 것들을 처리하게 된다.
따라서 이 Service를 Controller에서 사용할 수 있도록 해줘야한다.

Dependency Injection

constructor에서 의존성 주입이 이루어진다.
이를 통해 Controller에서 해당 Service를 이용할 수 있게 되는 것이다.

import {Controller} from '@nestjs/common';
import {UsersService} from './users.service';

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

위의 코드는 typeScript기능을 사용해서, userService파라미터에 userService객체를 타입으로 지정해준다.

이전 코드(접근 제한자를 사용하기 전)

@Controller('users')
export class UsersController{
	usersService: UsersService;
  
  	constructor( usersService: UsersService){
    	this.usersService = usersService;
    }
  
  @Get()
  getAllUsers(): User[]{
  	return this.usersService.getAllUsers();
  }
}
  • 3️⃣ usersService: UsersService
    : TypeScript에서는 선언한 값만 객체 프로퍼티로 사용할 수 있어서 이렇게 타입을 선언해준다.
  • 1️⃣ constructor( usersService: UsersService){
    :usersService파라미터에 UsersService 객체를 타입으로 지정한다.
  • 2️⃣ this. usersService = usersService
    : UsersController에서 사용할 수 있도록 this.usersService usersService를 할당해준다.
참고)

같은 프로퍼티의 경우 이 색으로 구분
같은 파라미터의 경우 이 색으로 구분

접근 제한자 사용

위의 코드를 간단하게 만들기 위해서는 접근 제한자(public, protected, private)을 생성자 파라미터에 선언한다.
이렇게하면, 해당 생성자 파라미터는 클래스 프로퍼티로 선언된다.

import {Controller} from '@nestjs/common';
import {UsersService} from './users.service';

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

	getAllUsers(){
    	this.usersService.getAllUsers();// 서비스 안의 메소드 사용
    }

위의 코드를 보면 접근 제한자를 사용하여 코드를 간단하게 만들 수 있는 것을 확인할 수 있다.
여기서 private을 선언했는데,
이렇게되면, userService 프로퍼티는 UsersController 클래스 내부에서만 사용 가능하게 된다.


이 Service는 `Providers` 중의 하나이기 때문에, 아래 정리한 글을 보면서 Provider가 뭔지 알고 넘어가자.

Provider란?

Provider는 NestJS의 기본 개념 중 하나로 정보를 공유하거나 특정 기능을 수행할 때 사용된다.
예를 들어, DB 연결, API호출, 로깅 등을 수행하는 Service저장소인 Repository 모두Provider로 사용될 수 있는 것이다.
이외에도 Factories, Helpers모두 Provider로 취급될 수 있다.

Provider의 주요 아이디어는 의존성을 주입할 수 있다는 것이다.

의존성 주입
객체 간 관계를 구축하고 어플리케이션의 유연성과 확장성을 향상시키는 패턴.

따라서 Provider를 통해 클래스나 객체를 생성하고, 필요한 부분을 주입하여 다른 곳에서도 사용될 수 있다.
이렇게되면 코드가 변경되거나 확장될 때, 기존의 코드를 최소한으로 수정하면서 새로운 기능을 추가하거나 변경할 수 있다.

예 #01

Service가 DB와 연결해야할 때, 연결 객체를 생성하는 Factory를 Provider로 주입받아 사용할 수 있다.
나중에 DB를 변경하거나, 다른 DB로 바꿀 때, Service를 수정하지 않아도 되기 때문에 유지 보수성을 증가시킬 수 있다.

예 #02

또 다른 예를 보자면, 하나의 Controller에 필요한 모든 기능들을 Controller에 구현할 수 없다.
따라서 Controller에 필요한 기능들을 Services, Factories, Repositories, Helpers들을 Controller에서 사용할 수 있도록 만드는 것이다.

Provider 사용 방법

Provider를 사용하기 위해서는 module에 등록해야한다.
module 파일 내부에서 providers 부분에서 해당 모듈에서 사용하려는 Provider들을 넣어주면 된다.

@Module({
	controllers: [UsersController],
  	providers: [UsersService],
})
export class UsersModule {}

정리 Ꙭ̮

Provider에서 가장 중요한 것은 바로 의존성을 주입할 수 있다는 것이다.
Provider를 통해 필요한 기능들을 생성하고, 필요한 곳이 있다면 다른 곳에서 해당 기능을 주입해 사용할 수 있다.
이에 따라 코드의 재사용성과 유지보수성을 높여주며, 확장성을 강화시켜준다.


참고
NestJS 공식문서

profile
👩🏻‍💻

0개의 댓글