(Nest.js 공부중)
Nest.js로 간단한 게시판 CRUD를 만들어 봄. DB는 포함하지 않고 컨트롤러와 서비스 파트만 구현했는데, 확실히 Express를 쓸 때보다 간단했다.
- @Param() 에게는 req.params가 맡았던 파라미터 변수를 넣어주면 되고,
- @Body()가 장식하는 변수 data에게는 DTO를 타입으로 넣어주면 된다.
- @Controller(’큰라우트’) 클래스와, 그 안의 @Get(’/작은라우트’) 같은 메소드들이 묶여 ⇒ ‘http://localhost:3000/큰라우트/작은라우트’ 와 같은 최종 url을 형성한다. 큰 라우트는 컨트롤러 데코레이션에, 작은 라우터는 메소드 데코레이션에!
- 데코레이션은 클래스나 함수 뿐만 아니라 변수에게도 붙는가?
Nest.js 실습 예제 - 게시판 만들기(1)
Nest.js 실습 예제 - 게시판 만들기(1)
* 명령어 실행 위치는 루트>src 안에서임 주의 *
Board 모듈 생성
/src> nest g mo board
// src/board/board.module.ts
import { Module } from '@nestjs/common';
@Module({})
export class BoardModule {}
Board 컨트롤러 생성
/src> nest g co board
// src/board/board.controller.ts
import { Controller } from '@nestjs/common';
@Controller('board')
export class BoardController {}
Board 서비스 생성
/src> nest g s board
// src/board/board.service.ts
import { Injectable } from '@nestjs/common';
@Injectable()
export class BoardService {}
이렇게 3가지를 다 만들고 나면 루트 모듈인 AppModule의 import 란에도 변화가 생김:
// app.module.ts
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { BoardModule } from './board/board.module';
@Module({
imports: [BoardModule],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}
→ 어떻게 알고 imports 란에 board를 넣은 건지는 몰라도. 그냥 새로 생성되는 하위 module들은 다 imports 파트에 넣어버리는 건가? 어차피 필요해서 만들었을 테니까, 하면서?
board.module.ts도 최종적으로는 알아서 이렇게 수정된다:
import { Module } from '@nestjs/common';
import { BoardController } from './board.controller';
import { BoardService } from './board.service';
@Module({
controllers: [BoardController],
providers: [BoardService]
})
export class BoardModule {}
Nest.js 실습 예제 - 게시판 만들기(2)
Nest.js 실습 예제 - 게시판 만들기(2)
추가 패키지: npm i lodash class-validator class-transformer @nestjs/mapped-types
(tsconfig.json에 속성 추가: “esModuleInterop”: true
)
lodash
: 코드 작성시 편하고 유용한 메소드들을 제공하는 유틸성 패키지.
class-validator
: 입력값 유효성 검사에 유용한 기능들 제공.
class-transformer
: html 요청시 항상 문자로 전달되는 파라미터 타입을 바꿔줌.
@nestjs/mapped-types
: 한 DTO 클래스에서 작은 부분 집합들을 카피해줌.
- esModuleInterop(true): ES6 모듈 사양을 준수하여 CommonJS 모듈을 가져올 수 있도록 한다. 즉, Commonjs 방식으로 내보낸 모듈을 es모듈 방식인 import로 가져올 수 있게 해줌!
DTO, Data Transfer Object
: Nest.js에서 클라이언트로부터 데이터를 받거나 줄 때 사용(해야)하는 객체. Nest.js의 모든 데이터는 DTO를 통해 운반된다.
: Express의 req.body와 같은 역할. 클라이언트로부터 데이터를 받아 준다. (되돌려주기도 함)
update 메소드의 DTO 예시1 (@nestjs/mapped-types
를 쓰기 전) :
// update-article.dto.ts
import { CreateArticleDto } from './create-article.dto';
import { IsString, IsNumber } from 'class-validator'
export class UpdateArticleDto {
@IsString()
readonly title: string;
@IsString()
readonly content: string;
@IsNumber()
readonly password: number;
}
⇒ 기본적으로 넘겨받는 데이터(속성) 하나하나 타입을 검사한다. 형식에 안 맞으면 자동으로 400 에러를 뱉어낸다.
예시2. @nestjs/mapped-type
도입 후:
//update-article.dto.ts
import { PartialType } from '@nestjs/mapped-types';
import { CreateArticleDto } from './create-article.dto';
export class UpdateArticleDto extends PartialType(CreateArticleDto) {};
에러 reify:fsevents: sill reify mark deleted 무한 로딩 - ❌
에러 reify:fsevents: sill reify mark deleted 무한 로딩 - ❌
발생 상황: npm uninstall class-validator 그리고 npm i @nestjs/mapped-types 등
에러 메세지 전문:
에러 메세지도 뜨지 않고, 여기서 멈춘 채로 더 진행되지 않는다.
시도:
- 처음에 @nestjs/mapped-types 설치할 때 ‘class-validator 의존성 이유로 실패하면’ class-validator를 삭제하고 @nestjs/mapped-types을 설치해보라고 하길래 그렇게 했는데, class-validator가 삭제조차 되지 않는다.
- npm cache clean --force 이것으로 잘 됐다는 사람도 있었으나 내 문제는 해결되지 않음.
원인:
찾아보니, Mac 전용의 fsevents라는 패키지가 같이 설치되느라 문제가 발생하는 것 같다.
시도2:
npm i --no-optional 이렇게 해보기. optional dependencies를 설치하지 않겠다는 플래그이므로 그 중 하나인 fsevents도 생략되게 되어 문제가 해결되어야 하는데…
그 후에도
에러: idealTree: timing idealTree Completed in 2042ms
에러: reify:class-validator: http fetch GET 200 https://registry.npmjs.org/class-validator/-/class-val
같은 무한 로딩 에러들이 자꾸 발생했다.
시도3:
설치중인 것을 Ctrl+c로 멈추고, node_module을 통째로 지워본다. 캐시를 제거하고(npm cache clean --force) node_modules를 다시 설지한다(npm i)
이번엔 여기서 걸린다..:
reify:rxjs: http fetch GET 200 https://registry.npmjs.org/
다시 지우고 실행했더니 이번엔 여기서:
reify:rxjs: timing reifyNode:node_modules/@angular-devkit/
이번엔 또 여기서:
reify:rxjs: timing reifyNode:node_modules/inquirer/nod
그담에 --no-optional로 했을 땐 여기서:
reify:rxjs: timing reifyNode:node_modules/@angular-dev
와 난리났네..
시도5: 실행중인 dev server 멈추고 하기. ⇒ 나는 서버를 실행중에 있지 않으므로 패스.
시도6: npm v8.18.0(최신버전)을 node 16.6으로 다운그레이드해보기 ⇒
일단 미완으로 놔둔다.
무슨 문법?
무슨 문법?
// src/board/board.controller.ts
@Put('/articles/:id')
updateArticle(@Param('id') articleId: number, @Body() data: UpdateArticleDto,) {
return this.boardService.updateArticle(
articleId,
data.title,
data.content,
data.password,
);
}
req.params.id를 대신하는 게 저 @Param(’id’)이고, req.body를 대신하는 게 저 @Body()라는 것은 알겠다.
그런데 저 문법이 대체 뭐지? readonly나 private과 비슷하게 저 자리에 들어가는 것은 뭔가.
클래스나 함수에 장식해준다고 했는데, 변수에도 장식해줄 수가 있는 건가? 그래서 데코레이터가 저렇게 쓰인 건가?
Uploaded by N2T