Express 프레임워크 사용 로직
Node.js (Express 내장 X)
Index.js - > route -> Controller
NestJS (Express 내장)
Module -> Controller -> Service
# NestJS 라우팅 설정 - 엔드포인트 관리
NestJS는 Express를 내장하고 있기에, Express에 대한 설정이 필요없다.
그리고, NestJS는 라우팅 파일을 별도로 생성하지 않고,
Controller에서 Get, Post, Delete 메소드들을 호출하고, 엔드포인트를 할당해준다.
(Module 파일에서 할당된 라우트별로 모듈을 만들고, 이에 따라서 클라이언트가 접근가능하게 해준다.)
main.ts -> Module.ts -> Controller.ts -> Service.ts
클라이언트 - 서버(NestJS)의 관계
서버는 기본적으로 URI를 통해 통신하며,
이때 URI의 엔드포인트를 중심으로
서버 API의 기능들이 나뉜다.
그렇기에, 클라이언트는 서버 URI + 사용하고자하는 기능의 엔드포인트로
서버에게 요청을 보내고, 서버는 이에 대응하여 응답 값을 클라이언트에게 제공한다.
클라이언트 - 서버의 관계는 다음과 같고,
본격적으로 클라이언트의 요청에 대한 적절한 응답을 해주는 로직인
src 폴더에 대해서 자세히 알아보도록 하겠다!
클라이언트의 요청을 처리하는 src 폴더의 구성
클라이언트가 서버에게 요청을 보내고 이에 대한, 응답을 처리해주는 곳이 src 폴더이다.
이제, src폴더의 구성에 대해 알아보고
src폴더에서 클라이언트의 요청에 대해 응답을 만들어내는 흐름을 알아보도록 하겠다.
NestJS의 src 로직은 다음과 같다.
Module -> Controller -> Provider
모듈부터 프로바이더까지 하나씩 살펴보도록 하자.
모듈(Module) 이란?
모듈은 @Module() 데코레이터로 주석이 달린 클래스이다.
각 응용 프로그램(NestJS 프로젝트) 에는 하나 이상의 모듈 (루트 모듈)이 있다. 루트 모듈은 Nest가 사용하는 시작점이다.
# 모듈의 의미
모듈은 밀접하게 관련된 기능 집합으로 비슷한 구성 요소를 구성시키는데 효과적인 방법이다.
(모듈을 기능별로 구성해둔다. ex) 유저 모듈, 주문 모듈, 챗 모듈, 어드민 모듈, 게시글 모듈)
기능별로 비슷한 요소들끼리 묶어서 엔드포인트를 일치시킬 수 있고, 개발에 대한 분리를 시켜
분할된 작업으로 체계적으로 소스코드를 관리할 수 있다 ㅎㅎ~
# 모듈의 사용법 - NestJS 아키텍처는 그대로 유지한다.
같은 기능에 해당하는 것들은 하나의 모듈 폴더안에 넣어서 사용한다.
(UserController, UserService, UserEntity 다 같은 기능이기에 UserModule안에 넣는다.)
모듈은 기본적으로 싱글 톤이므로 여러 모듈 간에 쉽게 공급자의 동일한 인스턴스를 공유할 수 있다.
- 하나의 모듈에서 실행되어질 때, 다른 모듈에서 사용가능하다는 말이다. - 아마 객체개념으로써 활용되지 않을까?
Controller 란?
컨트롤러는 들어오는 요청을 처리하고 클라이언트에 응답을 반환한다.
컨트롤러는 @Controller 데코레이터로 클래스를 데코레이션하여 정의된다.
즉, Controller 클래스로 관리되며, 객체로써 활용될 예정이다~ - 백엔드 객체지향 처음으로 접해보자~!
# Controller의 내부 요소 Handler 란?
핸들러는 @Get, @Post, @Delete 등과 같은 데코레이터로 장식 된 컨트롤러 클래스 내의
단순한 메서드이다.
Provider 란?
프로바이더는 Nest의 기본개념이다. 대부분의 기본 Nest 클래스는 서비스, 레포지토리, 팩토리, 헬퍼 등을 Provider로 취급될 수 있다.
프로바이더의 주요 아이디어는 종속성으로 주입할 수 있다는 것이다.
즉, 객체는 서로 다양한 관계를 만들 수 있으며 객체의 인스턴스를 "연결"하는 기능은 대부분 Nest 런타임 시스템에 위임될 수 있다.
Service 란? - Provider 중 하나
Service는 소프트웨어 개발내의 공통개념이며, NestJS, JavaScript에서만 쓰이는 개념이 아니다.
@injectable 데코레이터로 감싸져서 모듈에 제공되며, 이 서비스 인스턴스는 애플리케이션 전체에서 사용될 수 있다. (서비스가 필요한 클래스에서 객체로 받아서 사용한다~)
# Service의 임무
서비스는 컨트롤러에서 데이터의 유효성 체크를 하거나, 데이터베이스에 아이템을 생성하는 등의 작업을 하는 부분을 처리한다.
# Service의 Injectable란?
Injectable 데코레이터는 NestJS가 이것을 이용해서 다른 컴포넌트에서 이 서비스를 사용할 수 있게(Injectable) 만들어 준다.
# Service의 동작
Controller 로부터 받아진 값을 통해 데이터베이스와 통신을 하게되는데,
이때 데이터베이스와 통신을 하기 위한 Request 데이터를 가공하고,
그리고나서, 가공된 Request 데이터로 데이터베이스에 요청을 보낸 후 응답을 받는다.
최종적으로 응답 값은 Controller에 전달해준다~
마치며,
Provider에는 Service를 비롯해서 레포지토리, 팩토리, 헬퍼 등이 있다.
지금은 Provider의 가장 기초적인 Service에 대해서만 알아보았고,
추가로 공부해보면서 Provider의 레포지토리, 팩토리, 헬퍼 등을 알아볼 것이다.
그렇기에, 현재 포스팅은 Provider의 가장 기초적인 Service에 대해서만 알아보았다고 참고하면 되겠다.
src 폴더 구성해보기 - 실습
모듈 생성하기
터미널 프로젝트 위치에서
아래 명령을 통해 모듈을 생성하자.
Nest CLI 명령어를 통해 원하는 모듈을 생성할 수 있다. - node.js 처럼 폴더를 개별로 만들필요없이, 명령어 하나로 아키텍처 구성해줌..
$ nest g module boards
# nest g module boards 명령 실행하기 전의 app.module.ts 파일의 코드
# nest g module boards 명령 실행 한 후의 app.module.ts 파일의 코드
nest CLI를 통해 루트 모듈에 Boards 모듈을 추가했다.
NestJS 자체에서 모듈을 쉽게 구성할 수 있게 명령어로 만들어 둔 것이다. - node.js 였음. 일일히 해줬어야했는뎅..ㅎ
그럼 이제, 생성한 Boards 폴더에는 Board 모듈이 있고,
이 폴더에 Controller, Service, Entity 등 NestJS 아키텍처에 따른 파일을 추가해서 개발을 진행하면 된다.
우선, NestJS의 기초적인 부분을 확실히 다루고 들어가기에 간략하게 정리해보았다!
Controller 생성하기
아래 명령어를 통해 (지정한 모듈의) 컨트롤러를 생성하자
명령 옵션 인자의 --no-spec은 테스트 코드를 제공하지 않고, 만들어라 라는 의미이다.
$ nest g controller boards --no-spec
그러면 아래와 같이 boards 모듈에 대응하는 컨트롤러 파일이 생긴 걸 볼 수 있다.
# CLI로 Controller 파일 생성하는 순서
NestJS가 지정한 아키텍처대로 프로젝트 폴더들을 체계적으로 관리할 수 있고,
NestJS CLI 명령을 통해 해당 아키텍처를 쉽게 생성할 수 있다.
지난 2달 전에 다뤘던 Node.js에 비하면 NestJS는 백엔드 개발에 더 최적화되어 있다는 걸 뼈저리게 느끼고 있다 ㅎㅎ..
폴더 구성이랑, 관리하는 방법이 너무나 쉽고 직관적이다..
Service 생성하기
이번에도 Nest CLI 아래 명령으로 Service를 생성하자.
Node.js에 비하면, 개발자를 신경많이 써줌...
$ nest g service boards --no-spec
그러면, 아래와 같이 boards 모듈에 대응하는 Service 파일이 생성된다.
[Controller에서 Service를 사용할 수 있게 만들기 - Service 종속성 주입]
Board Service를 Board Controller에서 이용할 수 있게 해준다. - Controller에서 Dependency Injection 설정을 해준다.
Service의 Dependency Injection 설정은 TypeScript의 "private" 같은 접근 제한자를 사용하여 설정한다.
(이는, JavaScript에서는 사용불가 하다고 함.)
# TypeScript 특성을 이용해 Dependency Injection 설정
@Controller('boards')
export class BoardsController{
// BoardsService 클래스를 객체로 선언함.
boardsService: BoardsService;
constructor(boardsService: BoardsService){
this.boardsService = boardsService;
}
}
# 접근제한자 private를 이용해 Dependency Injection 설정
@Controller('boards')
export class BoardsController{
constructor(private boardsService: BoardsService){
}
}
'📚 스터디 > 백엔드' 카테고리의 다른 글
[개인 스터디] NestJS 정복하기 #03 - 게시글 생성 API | Create API (0) | 2022.10.28 |
---|---|
[개인 스터디] NestJS 정복 - CRUD API 구현 (0) | 2022.10.27 |
[개인 스터디] NestJS 정복하기 #01 - NestJS 템플릿의 이해 (0) | 2022.10.27 |
[개인 스터디] NestJS을 시작하며 - NestJS 개발환경 셋팅 (2) | 2022.10.22 |
[Node.js] 10주차: 로그인 구현 (0) | 2022.07.25 |