LoginSignup
4
1

More than 3 years have passed since last update.

NestJS+TypeORMでDB接続して動作確認まで

Last updated at Posted at 2020-09-12

基本的に自分用メモです.

DBの準備

今回はmysqlを使います.

予め適当なデータベースとユーザを作成して権限付与までしておきます.テーブルはまだ作らなくてOKです.

CREATE DATABASE testdb;
CREATE USER 'testuser'@'localhost' IDENTIFIED BY 'password';
GRANT ALL ON testdb.* TO 'testuser'@'localhost';

NestJSのプロジェクト作成

NestJSのプロジェクトを作成して簡単な動作確認まで行います.

細かいところは公式ドキュメントを参照: https://docs.nestjs.com

npm i -g @nestjs/cli
nest new nest-typeorm-handson // とりあえずnpm選択して進めます
nest g module user
nest g controller user
nest g service user

これでnest-typeorm-handson以下にこんな感じにファイルが生成されます.

src
├── app.controller.spec.ts
├── app.controller.ts
├── app.module.ts
├── app.service.ts
├── main.ts
└── user
    ├── user.controller.spec.ts
    ├── user.controller.ts
    └── user.module.ts

最低限の動作の追加

UserServiceに以下を追加します

user.service.ts
sample(): string {
  return 'UserService';
}

UserControllerに以下のコンストラクタとメソッドを追加します.

user.controller.ts
constructor(private readonly service: UserService) {}
@Get()
get() {
  return this.service.sample();
}

npm run startで起動し,ブラウザでlocalhost:3000/userにアクセスするとUserServiceの文字が出るはずです.

これで準備完了です.

TypeORMを使ってDB接続する

ここからTypeORMの出番です.

まずは準備します.

npm install --save @nestjs/typeorm typeorm mysql

そしてAppModuleの@Moduleの中身のimportsを以下のように書き換えます

app.module.ts
imports: [
  UserModule, // UserModuleはもともと追加されています
  TypeOrmModule.forRoot({
    type: 'mysql',
    host: 'localhost',
    port: 3306,
    username: 'testuser',
    password: 'password',
    database: 'testdb',
    entities: [],
    synchronize: false,
  })
],

さて,ここでnpm run startします.

すると以下のようなエラーが出る場合があります

[Nest] 70420   - 2020-09-11 22:23:00   [TypeOrmModule] Unable to connect to the database. Retrying (1)... +8ms
Error: ER_NOT_SUPPORTED_AUTH_MODE: Client does not support authentication protocol requested by server; consider upgrading MySQL client
    at Handshake.Sequence._packetToError (/Users/home/nest-typeorm-handson/node_modules/mysql/lib/protocol/sequences/Sequence.js:47:14)

これはユーザの設定関連が原因なのでmysqlで以下を実行すると治ります.

ALTER USER 'testuser'@'localhost' IDENTIFIED WITH mysql_native_password BY 'password';

次にEntityを作ります.src/user/user.entity.tsを作成し,以下のように作ります.

user.entity.ts
import { Entity, PrimaryColumn, Column } from "typeorm";

@Entity()
export class User {
    @PrimaryColumn({ length: 255 })
    id: string;

    @Column({ length: 255 })
    name: string;

    @Column()
    age: number;
}

さらにAppModuleに先ほど書いたDBの接続情報にこのEntityを使うことを教えてあげます.

app.module.ts
TypeOrmModule.forRoot({
            // 一部省略
      database: 'testdb',
      entities: [User], // <-追加
})

UserModuleには以下を追加します.

user.module.ts
imports: [TypeOrmModule.forFeature([User])],

そして,Repositoryの準備です.UserServiceを以下のように書き換えます.コピペでOKです.

user.service.ts
import { Injectable } from "@nestjs/common";
import { InjectRepository } from "@nestjs/typeorm";
import { User } from "./user.entity";
import { Repository } from "typeorm";
@Injectable()
export class UserService {
    constructor(@InjectRepository(User) private readonly repository: Repository<User>) {}
    sample(): Promise<Array<User>> {
        return this.repository.find();
    }
}

さて,ここでnpm run startしてlocalhost:3000/userにアクセスするとエラーが出ます.

エラー内容はER_NO_SUCH_TABLE: Table 'testdb.user' doesn't existです.そりゃあそうですね,テーブルまだ作って無いですから.

マイグレーション機能でテーブルを作る

EntityなどからDDLを生成することができます.

そのために一旦先ほども書いたDBの接続情報を以下のように./ormconfig.tsにも書きます.

ormconfig.ts
module.exports = {
    type: 'mysql',
    host: 'localhost',
    port: 3306,
    username: 'testuser',
    password: 'password',
    database: 'testdb',
    entities: ['src/**/*.entity.ts'],
    migrations: ['db/migrations/*.ts'],
    synchronize: false,
    cli: {
        migrationsDir: 'db/migrations'
    }
}

そしてpackage.jsonのscriptsに以下を追加します

"typeorm": "ts-node ./node_modules/.bin/typeorm --config ormconfig.ts"
npm run typeorm -- migration:generate -n Initialize

すると./db/migrationsに'数列-Initialize.ts'というファイルが生成され,中にはDDLが書かれていることがわかります.

そして,以下のコマンドを実行するとテーブルが作成されます

npm run typeorm migration:run
mysql> show tables;
+------------------+
| Tables_in_testdb |
+------------------+
| migrations       |
| user             |
+------------------+

そして再度npm run startすると起動できます

(もしかするとエラーが出るかもしれませんが,AppModuleのprovidersにUserServiceが指定されていたら消してください.自分の環境ではそれで治りました)

これで接続完了です.テーブルに適当にinsertしてからlocalhost:3000/userにアクセスするとinsertした内容が出力されるはずです.

4
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
1