블로그만들기(8) - Nest.js

anjoy·2021년 2월 18일
0

블로그만들기

목록 보기
8/13
post-thumbnail

도움을 얻은 곳
NestJS Document
노마드코더 - NestJS로 API만들기

기존에 여러 애플리케이션을 만들어보면서 대부분을 NodeJSExpress를 통해 서버를 구현했습니다. 프론트단을 타입스크립트 기반으로 수정하면서 백단 또한 타입스크립트 기반으로 구현해보아야겠다는 생각을 가지고 있던 중 친구의 Nest 홍보와

npm - @nestjs/core페이지의 Weekly Downloads 그래프의 꾸준한 상승 곡선을 보면서 이번 블로그용 서버는 Nest를 학습하며 진행해야겠다는 생각을 했습니다.

NestJS

Nest는 NodeJS에서 서버 측 애플리케이션을 구축하기 위한 프레임워크로 TypeScript기반의 OOP(Object Oriented Programming), FP(Functional Programming), FRP(Functional Reactive Programming) 지원합니다.

저는 Spring 프레임워크를 경험해본적은 없으나 여러 포스트나 주변의 지인들은 스프링과 유사한 느낌이라고 하네요.

시작하기

공식 Document를 따라 빌드해보았습니다.

$ npm i -g @nestjs/cli
$ nest new project-name

명령어를 이용해 새 프로젝트를 생성해봅시다.

.eslintrc는 제 입맛에 따라 조금 수정했습니다.

필요 모듈 설치 등이 끝나면 위와 같이 파일들이 생성됩니다.

$ npm run start:dev

명령어를 통해 잘 실행이 되는지 확인해봅시다.

터미널에 위와 같이 출력이 되었습니다. 저는 포트를 3075로 설정하였기때문에 브라우저에서 http://localhost:3075 주소로 접속해보겠습니다.

잘 접속이 되는 것을 확인했습니다.

// src/app.module.ts
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';

@Module({
	imports: [],
	controllers: [AppController],
	providers: [AppService],
})
export class AppModule {}

src/app.module.ts 의 코드를 보면 @Module이라는 특이한 함수를 볼 수 있습니다. 이것을 데코레이터라고 하는데 클래스에 함수 기능을 추가할 수 있게 해준다고 합니다.

노마드코더에 따르면 NestJS와 데코레이터는 함께하기 때문에 익숙해져야한다고 합니다.

http://localhost:3075 (default 3000)에 접속했을 때 Hello World! 라는 문자가 출력되었는데 src 폴더 내부에 있는 파일들의 코드를 살펴보면서 어떤 방식으로 출력된 것인지 확인해보겠습니다.

app.controller.ts에서 app.module.ts에서 호출한 AppController라는 @Controller 데코레이터와 함께하는 클래스가 있고 해당 클래스 내부에 @Get() 데코레이터가 보이는데 string 타입의 데이터를 반환하는 getHello() 함수가 있습니다.

이 함수는 app.service.ts에 선언되어 있는 AppService 클래스 내부의 getHello() 함수를 호출해서 'Hello World!'를 반환받고 요청한 클라이언트에게 전송해주는 것 같습니다. (Module -> Controller -> Service)

Controller

컨트롤러는 서버로 송신한 요청에 대해 응답하는 Express의 라우터 역할을 합니다.

컨트롤러는 최소 1개의 라우트를 가지며 각 라우트는 각자 해당하는 행동을 수행합니다.

이렇게 제가 컨트롤러를 여러개 선언하고 app.module.ts의 코드를

이렇게 수정해준다면 각 경로에서의 페이지는 아래와 같은 문자열이 출력됩니다.

  • / : Hello World!
  • /user : user controller
  • /post : post controller
  • /posts : posts controller

이때 컨트롤러에서 원하는 값들을 리턴할 수 있는데 왜 Service가 존재하는 걸까?

Provider

Nest는 컨트롤러를 비즈니스 로직과 구분하는 것을 권장합니다. 컨트롤러는 단지 URL을 받아오는 역할을 하고 함수를 실행시킬 뿐이지 나머지 Service, Repository 등의비즈니스 로직은 Provider로 분리시킵니다.

프로바이더의 주요 아이디어는 의존성을 주입하는 것으로 객체들의 다양한 관계를 생성시킬 수 있습니다.

의존성 주입이란? 간단하게 말하면 기능에 필요한 값들을 외부로부터 받아서 사용하는 것을 의미합니다.

프로바이더는 @Injectable() 데코레이터를 이용해 주석을 달 수 있습니다.

먼저 posts/post.service.ts 라는 파일에 프로바이더를 작성해보겠습니다.

import { Injectable } from '@nestjs/common';
import { InjectModel } from '@nestjs/sequelize';
import { Post } from './post.model';

@Injectable()
export class PostService {
	constructor(
		@InjectModel(Post)
		private postModel: typeof Post
	){}

	async getAllPost() {
		return await this.postModel.findAll();
	}

위와 같이 PostService라는 프로바이더에 getAllPost()라는 함수를 작성하였고, 컨트롤러에서 해당 함수를 받아 사용해보겠습니다.

// posts/posts.controller.ts

import { Controller, Get } from '@nestjs/common';
import {PostService} from './post.service';

@Controller('/post')
export class PostController {
	constructor(private readonly postService:PostService){};

	@Get()
	getAllPost() {
		return this.postService.getAllPost();
	}

이제 nest 서버에 url/post url에 GET 요청을 받으면 PostService 프로바이더의 getAllPost() 함수 실행 결과값을 받아 해당 값을 반환하는 응답을 보내줍니다.

클라이언트 단에서 이전에 Redux-saga를 연결해주었기 때문에 브라우저로 접속하면 getServerSideProps를 통해 LOAD_POSTS_REQUEST 액션이 디스패치되고 사가를 통해서 서버에 GET 요청을 전송 -> 응답받은 데이터를 저장하여 페이지에 렌더링되는 것을 볼 수 있습니다.

다음 포스팅은 NestJS에서 PasspostJWT를 통해 로그인과 access_token을 통한 세션유지를 구현해보려합니다.

profile
안녕하세요 벨로그에서 자기소개를 한 줄로 쓰라고 되어있는데 최대한 한 줄로 자기 소개를 해보겠습니다. 제 이름은 .....

0개의 댓글