A progressive Node.js framework for building efficient and scalable server-side applications.
Node.js 를 사용하는데 Express.js 프레임워크에 typescript로 빌드가 되며 타입스크립트와 express 에서 사용하는 라이브러리 등이 모두 활용 가능하다.
일단 typescript 를 사용하기에 정적 언어를 많이 써본 자바 개발자의 진입장벽이 현저히 낮아진..
1. 설치
brew install npm # node.js 패키지 매니저 설치
npm i -g @nestjs/cli # nest.js 의 새로운 프로젝트를 생성할 수 있게 하는 cli 패키지 매니저
2. 프로젝트 생성
nest new
$ nest 에서 제공하는 여러 커맨드.
3. 프로젝트 구성
$ nest new 에서 자동으로 생성되는 프로젝트 구조이다.
src
-- app.controller.ts # API 엔드포인트 @Controller 와 동일
-- app.controller.spec.ts # controller 테스트 파일
-- app.module.ts # controller, provider, 다른 모듈들은 import 하는 단위
-- app.service.ts # provider 라고 하는데 @Service 와 동일
-- main.ts # 앱 모듈 진입점 @SpringBootApplication 구동 시 애플리케이션 메인 진입점과 같다.
Modules
모듈은 위의 그림처럼 애플리케이션 구조를 구성할 수 있게 만들어주고 한 애플리케이션은 무조건 하나의 모듈을 가져야하고 그 루트 모듈에 다른 모듈을 import 해서 사용해야 한다. (위와 같은 형태의 구조면 OK)
Providers
Providers are a fundamental concept in Nest. Many of the basic Nest classes may be treated as a provider – services, repositories, factories, helpers, and so on. The main idea of a provider is that it can inject dependencies; this means objects can create various relationships with each other, and the function of "wiring up" instances of objects can largely be delegated to the Nest runtime system. A provider is simply a class annotated with an @Injectable() decorator.
위의 내용에서 말하듯이 서비스나 repository, factories, helpers(어쨌든 코드를 위임시키려고 만든 형태의 클래스를 말한다. 스프링에 빈으로 등록되는 @Component 와 동일하게 보면 되겠다.) 등이 서로 관계를 갖고 의존성 주입이 가능하고 활용이 가능한 컴포넌트라 보면 되겠다. @Injectable() 데코레이터(스프링에선 annotation) 를 달면 프로바이더라고 한다. 그래서 의존성 주입을 위해 생성자에 프로퍼티를 인자로 넣어주면 된다.
// Controller.ts
@Controller('movies') export class MoviesController {
constructor(private readonly moviesService: MoviesService) {}
@Get()
getAll(): Movie[] {
return this.moviesService.getAll();
}
}
// Provider -> Service.ts
@Injectable()
export class MoviesService {
private movies: Movie[] = [];
getAll(): Movie[] {
return this.movies;
}
}
Controllers
Request / Response 를 처리해주는 컴포넌트인데 스프링과 매우 유사하므로 코드만 예시로 적어둔다.
** 여기서 DTO 가 RequestBody 로 클라이언트로 부터 받아 맵핑하기 위해 등장하는데 간단하게 Validation이 가능하다.
@Controller('movies') export class MoviesController {
constructor(private readonly moviesService: MoviesService) {}
@Get()
getAll(): Movie[] {
return this.moviesService.getAll();
}
@Post()
create(@Body() movieData: CreateMovieDto) {
return this.moviesService.create(movieData);
}
@Delete('/:id') remove(@Param('id') id: string) {
return this.moviesService.deleteOne(id);
}
main.ts
파이프라고 주로 Validation 과 transform(input을 원하는 형태로 변경해서 서버에서 활용할 수 있게) 을 제공한다. 찾아보니 Filter, Inteceptor 처럼 라우팅을 해주기 전이나 모든 과정에서 사용하는 컴포넌트는 스프링 프레임워크에서 지원하는 것처럼 동일하게 사용할 수 있는 걸 보니, 스프링을 접해봤다면 이해하기 좋다.
// 애플리케이션의 글로벌 파이프라인에 ValidationPipe 를 추가한다.
app.useGlobalPipes(new ValidationPipe({
// 부가적인 옵션
whitelist: true,
forbidNonWhitelisted: true,
transform: true }
))
create-movie.dto.ts
export class CreateMovieDto {
@IsString() readonly title: string;
@IsNumber() readonly year: number;
@IsString() readonly genres: string[];
}
result
{ "statusCode": 400,
"message": [ "genres must be a string" ],
"error": "Bad Request"
}
** 추가로 위의 create-movie.dto.ts DTO 를 UpdateMovieDto 로 추가하되 모든 필드를 optional로 지정하고 싶은 경우가 생기거나 혹은 DTO 를 맵핑하기 위한 여러 기능을 제공하는 라이브러리는 @nestjs/mapped-types을 참고하면 된다.
`npm i @nestjs/mapped-types`
실행
package.json
"scripts": {
"prebuild": "rimraf dist",
"build": "nest build",
"format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"",
"start": "nest start",
"start:dev": "nest start --watch",
"start:debug": "nest start --debug --watch",
$ nest start:dev
정리하며
아주 간단하게 한 사이클을 돌려보았는데 소감을 말해보자면 자바스크립트는 항상 어려웠다. (제대로 배우지 않아서일 가능성이 매우 크지만.)
타입스크립트 기반에 스프링과 유사한 프레임워크 구조에 훨씬 설정이 간단하고(현재로선 json object mapper 나 validation정도) 컴파일 시간도 빠르고 node.js 서버 부트스트랩 도 매우 빠르다. 싱글 스레드 기반에 논 블로킹 IO 가 가능하고 이벤트 루프로 처리한다…이 정도의 개념 단어의 나열정도로 알고 있었지만, 앞으로 자세하게 확인해볼 만한 재미와 가치가 충분하게 느낄 수 있는 기회였다. 타입스크립트도 매력적인 것 같은데..더 보도록 해보겄다.
타입스크립트의 자세한 설명은 이 포스팅을 보면 되겠다.
Reference
'sub_project' 카테고리의 다른 글
마이크로서비스 패턴 1장 (0) | 2020.11.08 |
---|---|
서버를 컨테이너로 띄우자 (0) | 2020.06.12 |
BitBucket Deployment 파이프라인을 만들어보자 (3) | 2020.06.09 |
Elasticsearch Python API (0) | 2017.02.09 |
aws 웹서버 설정 (0) | 2016.04.16 |
댓글