Home Nestjs 기본 용어 정리
Post
Cancel

Nestjs 기본 용어 정리

NestJS

nest-js 구조

1
2
3
4
5
6
7
8
9
10
11
AppModule(root)
├──Module1
│   └──Controller
│   └──Service
│   └──..
│   └──..
├──Module2
│   └──Controller
│   └──Service
│   └──..
│   └──..

기본적인 명령어

프로젝트 생성

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

모듈생성

1
nest g module module-name

컨트롤러 생성

컨트롤러는 들어오는 요청을 처리하고 클라이언트에 응답을 반환한다.

1
nest g controller module-name

서비스생성

서비스 안에는 데이터베이스 관련된 로직을 처리한다.

1
2
nest g service module-name --no-spec
# --no-spce : 테스트 코드 생성 안함

Type ORM

설치

1
2
3
npm install pg typeorm @nestjs/typeorm --save
# pg : postgres 모듈
# typeorm : typeorm 모듈

설정

src > configs > typeorm.config.ts 파일을 만든다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import { TypeOrmModuleOptions } from '@nestjs/typeorm';
import * as config from 'config'; // 설정 파일 

const dbConfig = config.get('db');

export const typeORMConfig: TypeOrmModuleOptions = {
  type: dbConfig.type,
  host: process.env.RDS_HOSTNAME || dbConfig.host,
  port: process.env.RDS_PORT || dbConfig.port,
  username: process.env.RDS_USERNAME || dbConfig.username,
  password: process.env.RDS_PASSWORD || dbConfig.password,
  database: process.env.RDS_DB_NAME || dbConfig.database,
  entities: [__dirname + '/../**/*.entity.{js,ts}'], // entity가 정의된 위치
  synchronize: dbConfig.synchronize, // true이면 entity가 변경시 해당 table 삭제 후, 다시 생성
};

Entity 작성

db table의 설계도 같은 느낌 (Django에서 Model과 비슷한 느낌) 각각의 모듈폴더 안에 xx.entity.ts에 작성한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
@Entity('users')
export class User extends BaseEntity {
  @PrimaryGeneratedColumn()
  pk: number;

  @Column()
  id: string;

  @Column()
  password: string;

  //외레키 설정
  // OneToMany이면 Django에서 역참조라고 생각하면 된다.(_set으로 접근)
  // eager는 해당 모델을 가져올 때, userTires를 가져올지 설정하는 문구이다.
  @OneToMany((type) => UserTire, (userTire) => userTire.user, { eager: false })
  userTires: UserTire[];
}

근데, ts는 카멜케이스 이니깐 컬럼명을 카멜케이스로 하면 db에도 카멜케이스 형태로 들어간다.

이것을 DB에 들어갈때는 스네이크 케이스로 하고 싶으면 다음과 같이하면된다.

1
2
@Column({name:'created_at'})
createdAt: Date

하지만 이 방법은 번거럽고 실수 할 수 있다. 따라서 typeorm-naming-strategies를 사용해서 자동을 바뀔 수 있도록 한다.

1
2
3
export const typeORMConfig: TypeOrmModuleOptions = {
  // typeORMConfig에 다음과 같이 추가
  namingStrategy: new SnakeNamingStrategy(),

Repository

각 table의 CRUD를 하는 곳 Django에서 Manager(objects)랑 비슷한 느낌 각각의 모듈폴더 안에 xx.repository.ts에 작성한다. 기본적으로 Repository를 상속받은 형태로 작성하고, 추후 필요한 ORM을 메쏘드 형태로 만든다.

1
2
3
4
5
import { EntityRepository, Repository } from 'typeorm';
import { User } from './users.entity';

@EntityRepository(User)
export class UserRepository extends Repository<User> {}

만든 Repository를 Module에서 사용할 수 있도록 등록한다.

1
2
3
4
@Module({
  imports: [TypeOrmModule.forFeature([UserRepository])],
...
})

service 부분에서 사용하므로 다음과 같이 선언해서 사용한다.

ts에서는 생성자의 private 인자로 들어가면 자동으로 맴버 property가 된다.

1
2
3
4
5
6
7
@Injectable()
export class UsersService {
  constructor(
    @InjectRepository(UserRepository)
    private userRepository: UserRepository,
  ) {}
}

DTO

계층간 데이터를 전송하기 위해서 필요한 객체이며, 해당 객체를 만들기 위해서는 아래와 같은 패키지가 필요함.

파이프 data transformation과data validation을 위해서 사용됨 transformation : 정수로 받았는데, 숫자로 변환 validation : 유효성 체크

1
npm install class-validator class-transformer --save

파이프는 핸들러, 파라미터, 글로벌 레벨 3가지로 나뉨 핸들러: 핸들러 하나의 작용(컨토롤러 함수 하나) 파라미터 : 파라미터 하나의 적용 글로벌 : 모든 요청에 적용

로그인/회원 가입

bcryptjs

bcryptjs 단방향 해쉬 알고리즘으로 회원가입시, 비밀번호를 암호화 하기위해 사용 다양한 언어로 되어 있고 사용방법도 거의 동일한 것 같다. 참고

1
npm install bcryptjs --save
1
import * as bcrypt from 'bcryptjs';

로그인/인증

  • jwt: 로그인 시에 인증정보를 암호화한다.
  • passport: 토큰이 유효한지 검사하고 user정보를 반환하는 기능을 수행한다. 참고
    1
    
    npm install @nestjs/jwt @nestjs/passport passport passport-jwt --save
    

Test

테스트 파일을 작성하면 에러가 날때가 있다. package.json에서 jest 찾아서 설정을 바꿔주자

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
  "jest": {
    "moduleDirectories": [
      "node_modules",
      "src"
    ],
    "moduleFileExtensions": [
      "js",
      "json",
      "ts"
    ],
    "roots": [
      "src"
    ],
    "testRegex": ".spec.ts$",
    "transform": {
      "^.+\\.(t|j)s$": "ts-jest"
    },
    "coverageDirectory": "../coverage",
    "testEnvironment": "node",
    "moduleNameMapper": {
      "src/(.*)": "<rootDir>/src/$1"
    }
  }
This post is licensed under CC BY 4.0 by the author.