728x90
완성코드
핵심
- 앱은 여러 개의 모듈로 구성됨.
- 모듈은 컨트롤러와 서비스로 구성됨.
- 컨트롤러는 url을 가져오고 함수를 실행한다.
- 서비스는 실제로 function을 가지는 부분이다. 필요하다면 db에 접근도 한다.
0.1 Welcome
- node.js 위에서 움직이는 프레임워크. (사실 express 위에서.)
- node.js에 서버 구성할 수 있게 해줌.
- 다른 node.js 프레임워크에는 없는 구조를 가지고 있다.
- nest.js는 구조가 있다. 그것을 따르기만 하면 큰 규모의 백엔드를 쉽게 만들 수 있다.
- nest.js 배우면 express.js로 돌아갈 수 없다!
- node.js는 구조가 없어 자유롭다.
- express의 미들웨어와 같은 것이다.
- 결론: 아주 좋은 아키텍처를 가지고 있다.
0.2 Requirements
- node.js의 문제점을 알고있거나, 사용해본 적이 있어야 한다.
- nest.js는 100% typescript에 기반하고 있다.
- insomnia 설치. RESP API 써야하니까. Rest 클라이언트다.
- 추가로 nest.js에 대해 알아본 것들
0.3 Project Setup
npm i -g @nestjs/cli
nest new
- npm 선택
- github repository 만들기
1.0 Overview
- nestjs는 이미 만들어진 기능을 제공한다.
- typescript도 이미.
- src/app.controller.spec.ts는 삭제한다.
- 남는건 main, module, controller, service
npm run start:dev
- nest 어플리케이션 시작 중 => localhost:3000 으로 갈 수 있다.
- 무조건 main.ts 파일을 가진다. 이 파일로부터 nestjs가 시작한다.
- app.module.ts
- 데코레이터는 클래스에 함수 기능을 추가할 수 있다.
- 클래스 위의 함수. 클래스를 위해 움직인다.
- module - controller - service
1.1 Controllers
- 모듈은 어플리케이션의 한 부분.
- 인증 담당 어플리케이션이 있다면 그게 users 모듈이 될 것이다.
- 인스타그램을 만든다면 photos, videos 모듈이 필요하겠지?
- 컨트롤러: url을 가져오고 함수를 실행한다. express의 라우터 같은 존재다.
- 코드1) app.controller.ts
- http://localhost:3000/hello url로 가보면 "Hello everyone"이 보일 것이다.
- 라우터를 세팅하지 않아도, @Get이라고만 해도 get 리퀘스트를 얻을 수 있다.
@Get('/hello') sayHello(): string { return 'Hello everyone'; }
1.2 Services
- 코드1처럼 그냥 string을 리턴하면 되는데 왜 service가 필요할까?
- 컨트롤러는 그냥 url을 가져오는 역할. 나머지 비즈니스 로직은 서비스로 간다.
- 서비스: 실제로 function을 가지는 부분이다. 필요하다면 db에 접근도 한다.
- app.module.ts에서 AppController, AppService 삭제하자. 처음부터 다시!
- app.controller.ts, app.service.ts도 삭제.
2.0 Movies Controller
- url을 가져오고 function을 실행하는 파일을 만들 것이다. => controller를 만들 것이다!=> 자동으로 src/movies 폴더가 생긴다. spec.ts 파일은 삭제.
nest g co // 이름은 movies
- movies.controller.ts
import { Controller, Get } from '@nestjs/common'; @Controller('movies') export class MoviesController { @Get() getAll() { return 'This will return all movies'; } @Get('/:id') getOne(@Param('id') id: string) { // id: string은 movieId: string여도 상관없다. return `This will return one movie with the id: ${id}`; } }
@Controller('movies') // ()로 바꾸면 localhost:3000/ 루트 url로 바뀐다.
- 이기 때문에 /movies url로 가야 보인다.
- Insomnia에서도 확인 가능
- movies.controller.ts - get, post, delete, patch
import { Controller, Get, Param, Post, Delete, Patch } from '@nestjs/common'; @Controller('movies') export class MoviesController { @Get() getAll() { return 'This will return all movies'; } @Get('/:id') getOne(@Param('id') id: string) { // id: string은 movieId: string여도 상관없다. return `This will return one movie with the id: ${id}`; } @Post() create() { return 'This will create a movie'; } @Delete('/:id') remove(@Param('id') id: string) { return `This will delete a movie with the id: ${id}`; } @Patch('/:id') patch(@Param('id') id: string) { // put은 모든 리소스를 업데이트, patch는 일부 리소스만 업데이트 return `This will patch a movie with the id: ${id}`; } }
2.1 More Routes
- Query
@Get('search') search(@Query('year') year: string) { // search가 Get(:id) 보다 밑에 있으면 Get(:id)로 인식한다. // search가 Get(:id)라고 생각하는거지. // http://localhost:3000/movies/search?year=2000 return `We are searching for a movie after: ${year}`; }
2.2 Movies Service part One (10:48)
- Single reponsibility principle
- 하나의 module, class 혹은 function이 하나의 기능은 꼭 책임져야한다.
- make service file
nest g s
- 여기서 생긴 spec.ts는 삭제하지 않는다.
- 서비스에서는 비즈니스로직, 데이터베이스를 다룰 것이다.
- 이 강의에서는 js object를 이용하지만, entities에 실제 데이터베이스 모델을 만들어야 한다.
- src/movies/entities/movie.entity.ts
- service를 가져오자.
- express에서 수동으로 import하는 방법이 nestjs에서는 기본적인 방법이 아니다.
- constructor 이용
- 최종코드
- tip
const str = '1'; // parseInt('1') === +str; // true
2.3 Movies Service part Two (08:03)
- POST하면 자동으로 201 이 status code로 뜬다.
- nestjs는 우리를 위해 미리 준비된 기능이 아주 많다.
- Not Found
throw new NotFoundException(`Movie with ID ${id} is not found.`);
- 최종코드: https://github.com/daheeahn/hi-nest/commit/98b79a68625caeefecbaac91fd97c31245800eef
2.4 DTOs and Validation part One (10:52)
- DTO: Data Transfer Object
- dto를 쓰는 이유? 코드를 더 간결하게 만들 수 있게 해줌. 들어오는 쿼리에 대해 유효성 검사할 수 있게 해준다.
- 클래스 유효성 검사를 위해 파이프 만들어줄거다. (미들웨어)
- 일단 설치할 것들.
npm i class-validator class-transformer
- 유효성 검사 - src/dto/create-movie.dto.ts
import { IsString, IsNumber } from 'class-validator'; export class CreateMovieDto { @IsString() readonly title: string; @IsNumber() readonly year: number; @IsString({ each: true }) // Array니까 각각 readonly genres: string[]; }
- 원하는 타입으로 바꿔준다. (transform 옵션 사용)
- 프레임워크의 유용성!
- 최종코드: https://github.com/daheeahn/hi-nest/commit/f86cdbcdc6000a551b804a657bb9d5f3733d581d
2.5 DTOs and Validation part Two (05:34)
- Create Dto와 다른 점: 필수가 아니라는 점. => PartialType 이용
- 설치
- 타입을 변환시키고 사용할 수 있게 해주는 패키지
npm i @nestjs/mapped-types
- update-movie.dto.ts
export class UpdateMovieDto extends PartialType(CreateMovieDto) {}
- 우리의 서버도 실시간으로 보호되고 있다. typescript의 보안을 사용할 수 있다.
- 최종코드: https://github.com/daheeahn/hi-nest/commit/7bdfe6dd3384b9c098ec990799693ffc4873e8ac
2.6 Modules and Dependency Injection (07:07)
- app.module.ts에는 AppController, AppService만 있어야 한다. (여러 개 있으면 X)
- 앱은 여러 개의 모듈로 구성됨.
- 모듈은 컨트롤러와 서비스로 구성됨.
- 컨트롤러는 url을 가져오고 함수를 실행한다.
- 서비스는 실제로 function을 가지는 부분이다. 필요하다면 db에 접근도 한다.
nest g mo
- 컨트롤러와 서비스를 가진 모듈을 만들었다. (app.module.ts 보다 작은 단위의)
- Service 보면 Injectable 데코레이터가 있다. 이건 컨트롤러에 주입 가능하다는 뜻.
- Module에서
providers: [MoviesService],
없애면 컨트롤러에는 provider 필요하다고 에러가 난다. - 최종 코드: https://github.com/daheeahn/hi-nest/commit/88dbb2a5e6ff61cb319a39af967419e45446714c
2.7 Express on NestJS (03:22)
- nestjs는 express 위에서 돌아간다. 필요 시 Req, Res 데코레이터 사용 가능.
- 그러나 이러한 express 객체를 사용하면 좋지 않다. 2개의 프레임워크와 작동하기 때문에
- 그래서 Fastify라는 걸로 전환시킬 수 있다.
- Nest는 Fastify 같은 라이브러리와 호환 된다. 이건 express보다 2배 빠르다. 같은 동작 하지만.
- 항상 nestjs에서는 어떤 방식으로 하는지 알아야 겠지.
- res.json() 작동할 것이다. (express에서 json 다루는 방식이기 때문에)
- nestjs만 사용하면 express에서 fastify로 전환 가능. (그렇지만 Res, Req 이건 사용하지 않을 것임)
- expree와 fastify 전환하고 싶을 때 nestjs가 알아서 해줄 것임. (성능 향상에 좋다)
- express에 접근 가능. Req, Res 사용 원하면. 그렇지만 추천 X. Fastify처럼 express와는 다른 방법 쓰고 싶을 수 있으니.
'Study > Backend' 카테고리의 다른 글
RDBMS와 NoSQL의 차이점 (0) | 2023.01.27 |
---|---|
[Server] GET과 POST의 param 전달방식이 다르다! in postman (0) | 2019.02.07 |