NestJS/Docker/postgreSQL/TypeORM で環境構築してDBにデータ登録する

NestJSのプロジェクトの新規作成から、DBへのデータ保存するところまでを書いていきます。

記事のゴール

  1. NestJSのプロジェクト作成
  2. docker-composeでpostgreSQL環境構築
  3. TypeORMインストール、DBとの接続設定
  4. DB migration
  5. DBへのデータ保存

バージョン

  • nestjs/common: 8.0.0
  • nestjs/core: 8.0.0
  • typeorm: 0.2.45
  • nestjs/typeorm: 8.0.2
  • postgreSQL: 14.2

NestJSのプロジェクト作成

公式サイトを参考に、NestJSのプロジェクトを作成していきます。

  • NestJS CLIインストール

CLIをインストールしていない方は、インストールしてください。

$ npm i -g @nestjs/cli
  • プロジェクト新規作成

プロジェクト名はnestjs-sampleとしています。 コマンド実行するとパッケージマネージャーについて聞かれます。 筆者はnpmを選択しましたが、お好きなものを選択してください。

$ nest new nestjs-sample

postgreSQLのDB環境構築

  • 作成したプロジェクト(nestjs-sample)配下にdocker-compose.ymlファイルを作成し、以下の内容を貼り付けてください。
version: '3.7'
services:

  postgres:
    image: postgres:14.2-alpine
    container_name: postgres
    ports:
      - "5432:5432"
    volumes:
      - ./postgres_data:/var/lib/postgresql/data
    environment:
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: postgres
      POSTGRES_INITDB_ARGS: '--encoding=UTF-8'
      POSTGRES_DB: postgres
    hostname: postgres
    restart: always
  • ターミナルで以下コマンドを実行し、postgreSQLのコンテナを立ち上げてください。
$ docker-compose up -d
$ docker-compose ps // DBコンテナが起動されていることを確認

TypeORMインストール・DBへの接続情報

今回はpostgreSQLを使用するので、pgとしています。

$ npm install --save @nestjs/typeorm@8.0.2 typeorm@0.2.45 pg
  • DBへの接続情報をormconfig.jsに書き出す
$ touch ormconfig.js
  • 作成したormconfig.jsに以下の内容を貼り付けてください。
module.exports = {
  type: 'postgres',
  host: 'localhost',
  port: 5432,
  username: 'postgres',
  password: 'postgres',
  autoLoadEntities: true,
  entities: ['dist/entities/*.entity.js'],
  migrations: ['dist/migrations/*.js'],
  cli: {
    entitiesDir: 'src/entities',
    migrationsDir: 'src/migrations',
  },
};

entities: ['dist/entities/*.entity.js']部分はmigrationファイルを作成する際に読み込むEntityの設定となります。TypeORMはデフォルトの設定で、コンパイル済みのjsファイルを読み込むので、コンパイル済みのdistディレクトリを指定する必要があるようです。

migrations: ['dist/migrations/*.js']部分はマイグレーションを行うファイルです。

cli: {...}部分はCLIによってentitiesやmigrationsが生成されるときの出力先となります。

  • TypeORMを使うために、TypeOrmModuleをAppModuleにインポートする

app.module.tsでTypeOrmModuleをインポート

import {TypeOrmModule} from "@nestjs/typeorm";

@Module({
  imports: [TypeOrmModule.forRoot()],  // TypeOrmModule.forRoot()をimportsに加える
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}

Entityt作成

  • Entityでテーブルを定義します。nestjs-sample直下にentitiesディレクトリを作成します。
$ mkdir src/entities
$ touch src/entities/user.entity.ts
  • 今回はuserテーブルを以下のように定義します。
import {Column, Entity, PrimaryGeneratedColumn} from "typeorm";

@Entity()
export class User {
    @PrimaryGeneratedColumn('uuid')
    id: string;

    @Column({ unique: true })
    username: string;

    @Column()
    password: string;
}
  • コンパイルすることで、nestjs-sample直下にdist/entities/user.entity.jsが作成されていることを確認してください。
$ npm run start:dev

マイグレーション

マイグレーションファイルを生成

$ npx typeorm migration:generate -n CreateUser

これで、src/migrations以下にmigrationファイルが生成されます。 上記コマンド実行時にエラーとなる場合は、nestjs/typeormやtypeormのバージョンによる可能性が考えられますので、バージョンを見直してみてください。

マイグレーション実行

生成されたmigrationファイルをコンパイルしてから、migration実行する必要があります。

$ npm run start:dev
$ npx typeorm migration:run

これでuserテーブルが作成されたことを確認してください。

intelliJでESLintの"TypeError: this.libOptions.parse is not a function"のエラーが出た

ESLint@8.0.1でTypeError: this.libOptions.parse is not a functionのエラーが出ました。ESLintのバージョンによっては、intelliJやWebStormで出てしまうようです。 以下を実行することでエラーが解消しました。

  1. ESLintのバージョンを8.22.0にする
  2. node_modulesとpackage-lock.jsonを削除する
  3. 再度npm installする
$ npm install eslint@8.22.0 --save-exact 
$ rm -rf node_modules
$ rm package-lock.json
$ npm i

参考