Nxで作成したnestjsのプロジェクトをmysqlと接続する

[これ](https://qiita.com/Gma_Gama/items/f862e7497a9c279b00da)の続きです

# Nxで作成したnestjsのプロジェクトをmysqlと接続する

### Table of Contents

0. dockerで簡易的にmysqlを作成
1. MySql などのデータベースと接続
2. MySql のデータベースと接続(typeormを用いてapplicationを接続する)

## 1. dockerで簡易的にmysqlを作成

現行のディレクトリ構成は以下のような形を想定しています。

```terminal
$ tree -L 1 -I node_modules
├── README.md
├── apps
│   └── nestjs-sample
│       ├── jest.config.js
│       ├── src
│       │   ├── app
│       │   │   ├── app.controller.spec.ts
│       │   │   ├── app.controller.ts
│       │   │   ├── app.module.ts
│       │   │   ├── app.service.spec.ts
│       │   │   ├── app.service.ts
│       │   │   └── todo
│       │   ├── assets
│       │   ├── environments
│       │   │   ├── environment.prod.ts
│       │   │   └── environment.ts
│       │   └── main.ts
│       ├── tsconfig.app.json
│       ├── tsconfig.json
│       └── tsconfig.spec.json
├── jest.config.js
├── libs
├── nx.json
├── package.json
├── tmp
│   └── apps
│       └── nestjs-sample
│           └── tsconfig.generated.json
├── tools
│   ├── schematics
│   └── tsconfig.tools.json
├── tsconfig.base.json
├── workspace.json
└── yarn.lock
```

次に簡易的にmysqlのイメージを持ったdocker fileを作成します。

```
$ touch docker-compose.yml
$ touch Dockerfile
```

docker-composeの中身を記載します。

```docker-compose.yml
version: '3.8'
services:
  db:
    container_name: nestjs-sample-db
    image: mysql:5.7
    tty: true
    restart: always
    environment:
      MYSQL_DATABASE: nestjs-sample-db
      MYSQL_ROOT_PASSWORD: password
      MYSQL_USER: nestjs-sample-db
      MYSQL_PASSWORD: password
    ports:
      - '3306:3306'

```

Dockerの中身は以下にします。

```Dockerfile
FROM mysql:5.7
```

dockerの起動をしておきます。

```
$ docker-compose up
```

## 2. MySql のデータベースと接続(typeormを用いてapplicationを接続する)

実施するのはこの章のため、[公式ドキュメント](https://docs.nestjs.com/techniques/database)で対応したい方はこっちの方がいいと思います。

やることは一緒で、
1. TypeORMのinstall
2. TypeORMの有効化

を実施していきます。

### 2-1. TypeORMのinstall

依存関係のmoduleをinstallします。

```terminal
$ yarn add @nestjs/typeorm typeorm mysql
```

### 2-2. TypeORMの有効化

app.module.ts_を編集して、TypeORMを有効化していきます。

現状のapp.module.tsは以下です。

```app.module.ts
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';

@Module({
  imports: [],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}

```

ここにTypeOrmの設定を追記します。

```app.module.ts
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm'; ##ここを追記
import { AppController } from './app.controller';
import { AppService } from './app.service';

@Module({
  imports: [
  ##ここから追記
    TypeOrmModule.forRoot({
      type: "mysql",
      host: "localhost",
      port: 3306,
      username: "nestjs-sample-db",
      password: "password",
      database: "nestjs-sample-db",
      entities: ["dist/**/*.entity{.ts,.js}"],
      "synchronize": true
    }),,
  ##ここまで追記
  ],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}

```

公式ドキュメントでいくとこれで完了なのですが、Entityの設定をよみこまないのでTypeormModule.forRootに以下に変更します。


```app.module.ts
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { AppController } from './app.controller';
import { AppService } from './app.service';

@Module({
  imports: [
    TypeOrmModule.forRoot({
      type: "mysql",
      host: "localhost",
      port: 3306,
      username: "nestjs-sample-db",
      password: "password",
      database: "nestjs-sample-db",
      entities: [], ##ここ変更
      autoLoadEntities: true,
      synchronize: true　##ここ変更
    }),
  ],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}
```

"@nrwl/workspace": "10.3.1"だと、この設定だけだとうまく接続と、databaseのrelationがうまくいかないのでいつか記載します.(11/7時点でissueが上がっているが解決はしていない + tsconfigの書き換えでうまくいくが。。。って感じです)

ざっくりと記載すると、tsconfig.app.jsonとapp.module.tsを以下に変更します。

```tsconfig.app.json
{
  "extends": "./tsconfig.json",
  "compilerOptions": {
    "outDir": "../../dist/out-tsc",
    "types": ["node"],
    "emitDecoratorMetadata": true,
    "skipLibCheck": true,
    "module": "commonjs", // <-- here
    "target": "es2017", // <-- here
  },
  "exclude": ["**/*.spec.ts"],
  "include": ["**/*.ts"]
}

```

```app.module.ts
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { getMetadataArgsStorage } from 'typeorm';

@Module({
  imports: [
    TypeOrmModule.forRoot({
      type: "mysql",
      host: "localhost",
      port: 3306,
      username: "nestjs-sample-db",
      password: "password",
      database: "nestjs-sample-db",
      entities: getMetadataArgsStorage().tables.map(t => t.name),
      synchronize: true,
    }),
  ],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}

```

[レポ](https://github.com/Ntakuya/nest)