TypeScript + Express + typeORM으로 서버 세팅하기(2)

조성철 (JoSworkS)·2020년 2월 5일
3

이번 로그에서는 바로 앞의 TypeScript와 Express를 사용하여 서버를 구축하는 것에 이어 TypeORM으로 mySQL에 테이블을 만들고 데이터베이스에 연결하는 작업에 대해 기록하고자 한다.

먼저, TypeORM은 Sequelize와 같은 ORM의 한 종류이다. TypeORM에 대한 소개는 이전의 로그를 참고하도록 좋을 것 같다.
https://velog.io/@josworks27/typeORM-%EC%8B%9C%EC%9E%91%ED%95%98%EA%B8%B0

TypeORM 설정

먼저, TypeORM을 이용하여 Express서버와 MySQL을 연결하기 위한 설정을 했다. 이 부분은 전에 사용했던 시퀄라이즈와 큰 차이가 없었지만 cli를 사용하는데 있어서 별도의 스크립트 설정이 필요하다는 점에서 다소 불편하게 느껴졌다.(아직 생소하기 때문이라고 생각한다. TypeORM에 익숙해지고 많이 사용해보면 분명 다르게 느껴질 것이다.)

ormconfig.js 설정

TypeORM에서도 Sequelize와 마찬가지로 ORM을 사용하기 위한 설정작업이 필요하다. 먼저 비교를 위해 Stroll 프로젝트에서 설정한 Sequelize 옵션을 가져왔다.

// Sequelize
module.exports = {
  development: {
    username: process.env.DB_USER,
    password: process.env.DB_PASS,
    database: process.env.DB_NAME,
    host: process.env.DB_HOST,
    dialect: 'mysql',
    operatorsAliases: false,
  },
};
// TypeORM
{
module.exports = {
  type: 'mysql',
  host: process.env.DB_HOST,
  port: process.env.DB_PORT,
  username: process.env.DB_USERNAME,
  password: process.env.DB_PASSWORD,
  database: process.env.DB_DBNAME,
  synchronize: true,
  logging: false,
  entities: ['src/entities/**/*.ts'],
  migrations: ['src/migration/**/*.ts'],
  subscribers: ['src/subscriber/**/*.ts'],
  cli: {
    entitiesDir: 'src/entities',
    migrationsDir: 'src/migrations',
    subscribersDir: 'src/subscriber',
  },
};

위 Sequelize와 비교했을 때 TypeORM의 설정은 큰 차이가 있지는 않다. 기본적으로 type(dialect), host, username, password, database 등과 Sequelize에서는 기본값이어서 생략되어 있지만 port도 마찬가지로 설정하게 된다.

하지만 TypeORM에서는 그 외에도 추가적인 옵션으로 synchronize, logging, entities, migrations, subscribers, cli 등의 옵션을 사용할 수 있는데, 각각의 옵션은 다음과 같은 목적을 갖고 있다.

  • synchronize: 애플리케이션에 작동할 때마다 DB Schema가 자동으로 만들어지게 할 것인가를 설정
  • logging: 로깅을 할 것인가 하지 않을 것인가를 설정
  • entities: 연결에 사용되며 로드되는 entity. 설정한 entity class와 로드하기 위한 directory path를 허용
  • migrations: 연결에 사용되며 로드되는 migration. 설정한 migration class와 directory를 허용
  • subscribers: 연결에 사용되며 로드되는 subscriber. 설정한 subscriber class와 directory를 허용
  • cli.entitiesDir: CLI에 의해 기본값으로 생성되는 entity 디렉토리
  • cli.migrationsDir: CLI에 의해 기본값으로 생성되는 migration 디렉토리
  • cli.subscribersDir: CLI에 의해 기본값으로 생성되는 subscriber 디렉토리

이렇게 설정하고 createConnection 메소드로 실행시키면 데이터베이스의 설정대로 서버와 데이터베이스가 연결된다.

Entity 정의하기

처음에는 시퀄라이즈와 정의하는 방식이 달라 낯설게 느껴졌다. 먼저 타입스크립트를 사용하기 때문에 각 컬럼에 타입을 지정해줘야 하고 @데코레이션을 사용하여 컬럼의 기능을 정의한다는 점에서 생소하게 느껴졌다.

그리고 created_at과 updated_at이 디폴트로 적용된다고 공식문서에서 봤는데 적용되지 않아 import하고 이름을 만들어 주었다.

import {
  BaseEntity,
  Entity,
  PrimaryGeneratedColumn,
  Column,
  CreateDateColumn,
  UpdateDateColumn,
} from 'typeorm';

@Entity()
export class User extends BaseEntity {
  @PrimaryGeneratedColumn()
  id!: number;

  @Column()
  email!: string;

  @Column()
  password!: string;

  @Column()
  name!: string;

  @Column()
  mobile!: string;

  @Column()
  gender!: string;

  @Column({ type: 'date' })
  birth!: string;

  @Column({ nullable: true })
  currentPlan!: string;

  @Column({ nullable: true })
  expiry!: string;

  @Column({ nullable: true })
  livingHouse!: number;

  @Column({ type: 'boolean' })
  isActive!: boolean;

  @CreateDateColumn({ name: 'created_at' })
  createdAt!: Date;

  @UpdateDateColumn({ name: 'updated_at' })
  updatedAt!: Date;
}

결론

처음엔 굉장히 낯설게 느껴졌는데 타입스크립트와의 호환성이 좋고 데코레이션을 사용하여 정의하는게 굉장히 편리하게 느껴졌다. 타입스크립트와 함께라면 TypeORM도 좋은 선택지가 될 수 있다고 생각한다.

하지만 Sequelize에 비해 cli를 이용하는데 있어 별도의 설정이 필요하다는 점에서 처음 활용하는 입장에서는 다소 어렵게 느껴지는 부분이 있었다. 그리고 뭔가 엄청나게 좋은 기능들이 많은데 너무 많은 기능 때문에 어떤 방식으로 접근하면 좋을지 고민하게 만드는 부분이 있었기에 자주 사용해보면서 최적의 사용법을 알아가는게 중요하다고 느껴졌다.

참고자료

3개의 댓글

comment-user-thumbnail
2020년 11월 10일

안녕하세요! TypeORM 사용에 대한 정보를 잘 제공해주셔서 감사합니다. 질문있습니다. 혹시 Database로 migration 작업을 할때 Table Name에서 대문자가 왜 안되는지 알 수 있을까요?

저는 @Entity({name:"User"}) 로도 지정해줬는데 자꾸 소문자로 나와서 문제입니다 ㅠㅠ

1개의 답글