LoginSignup
18
19

More than 3 years have passed since last update.

typeORM + Express で NodeJS バックエンドするメモ

Last updated at Posted at 2019-05-27

Express + TypeScript + MySQL + typeORM + routing-controllers でのサーバーサイド開発の雰囲気を掴むために知識を埋めていく過程のログです。

node: 12.2.0
typeorm: 0.2.17
typescript: 3.4.5

インストールと Typescript の設定

必要なパッケージのインストール。

yarn add mysql typeorm reflect-metadata
yarn add --dev @types/node nodemon ts-node typescript

tsconfig はゆるく作ります。

tsconfig.json
{
  "compilerOptions": {
    "target": "es5",
    "module": "commonjs",
    "lib": ["es2019"],
    "sourceMap": true,
    "outDir": "./build",
    "incremental": true,
    "removeComments": false,
    "downlevelIteration": true,
    "strict": true,
    "noImplicitAny": false,
    "strictNullChecks": true,
    "strictFunctionTypes": false,
    "strictBindCallApply": false,
    "strictPropertyInitialization": false,
    "noImplicitThis": false,
    "moduleResolution": "node",
    "forceConsistentCasingInFileNames": true,
    "esModuleInterop": true
  }
}

package.jsonに run & watch を追加します。

package.json
...
"scripts": {
  "start": "nodemon --exec ts-node -- ./src/index.ts"
},
...

typeORMのQuick Start

ここからtypeORMのQuick Start を進めます。typeormのコマンドを使ってプロジェクトを作るように指示されます。すでにプロジェクトを作っていたので typeorm init --database mysql しました。

You can also run typeorm init on an existing node project

typeorm initするとtsconfig.jsonpackage.jsonが上書きされ、typescript関連モジュールのバージョンがダウングレードされてしまいます。これは嬉しくないのでpackage.jsontsconfig.jsonの変更を捨てて手動で変更します。

変更を捨ててtsconfig.jsonに以下を追加する必要があるようです。

tsconfig.json
...
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
...

動作確認

Quick Start に戻って指示通りormconfig.jsonにデータベースの情報を入れるとコードを動かせます。

npm run startして起動確認、データベースに正常に書き込まれているかどうかも mySQL Workbenchなどで確認します。
指定したデータベースにUser テーブルが追加されユーザーが追加されていれば正解です。

@Enityでテーブルを定義する

@Enityでテーブルを定義できます。columnの型は自動で入りますが、指定することもできます。参考: Column types

entity/Photo.ts
@Entity()
export class Photo {
    @PrimaryColumn()
    id: number;

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

    @Column("text")
    description: string;

    @Column("double")
    views: number;

    @Column()
    isPublished: boolean;
}

ここで気になったのがentityを変更するとデータベースのテーブルも変更してしまう点です。レコードがあろうとentityを変更して実行するたびにデータベースのテーブルが変更されます。これは怖い。

この動作はormconfig.jsonsynchronizefalseにすることで解決することができました。

TypeORM Migrations

上記のとおりsynchronize: false にするとEntityのコード変更でデータベースが変更されることはなくなります。
変わりに「Entityを作る → migrationファイルの生成 → migrationファイルの実行」という流れにします。

migration ファイルを作る

テーブルの追加や変更はtypeorm migrationを使ってすることになります。データベース上のテーブルとEntityの差分からmigrationファイルを作ってくれます。

typeorm migration:generate -n changeEntity

ところでSyntaxError: Unexpected token {というimportできないエラーがでてしまいました。ググったところts-nodeで解決するようなので ./node_modules/.bin/ts-node ./node_modules/.bin/typeorm migration:generate -n changeEntity します。

migration ファイルを実行する

generateしたmigrationファイルを実行します。

typeorm migration:run // したい
./node_modules/.bin/ts-node ./node_modules/.bin/typeorm migration:run

./node_modules/.bin/ts-node ./node_modules/.bin/typeormはめんどうなので他の解決作を探したいところですが。時間がもったいないので、そのまま npm scripts に入れておきます。

参考: Migrations - typeORM

typeORM + routing-controllers

最後にrouting-controllersを試します。typeorm-routing-controllers-extensionsがあるのでこれを導入していきます。 https://github.com/typeorm/typeorm-routing-controllers-extensions のReadmeを参考に進めました。

必要なパッケージなどをインストールします。


yarn add express typeorm-routing-controllers-extensions routing-controllers
yarn add --dev @types/express

typeORMの Quick Start で作ったデータベースとデータを使ってrouting-controllersを試していきます。

ここでsrc 以下のファイル構成はおさらいしておきます。

src/
 ├ entity/
 │ └ User.ts
 ├ migration/ ...
 ├ index.ts             ← 変更します。
 └ controller/          ← 新規ディレクトリ。
    └ UserController.ts  ← 新規ファイル。

UserControllerを作ってindex.tsから読み込みます。

controller/UserController.ts
import { Get, JsonController } from 'routing-controllers';
import { User } from '../entity/User';
import { EntityFromParam } from 'typeorm-routing-controllers-extensions';

@JsonController()
export class UserController {
  @Get('/users/:id')
  get(@EntityFromParam('id') user: User) {
    return user;
  }
}
index.ts
import 'reflect-metadata';
import { createConnection } from 'typeorm';
import { createExpressServer } from 'routing-controllers';
import { UserController } from './controller/UserController';

createConnection()
  .then(async connection => {
    createExpressServer({
      controllers: [UserController]
    }).listen(3000);
    console.log('Server is up and running on port 3000.');
  })
  .catch(error => console.log('Error: ', error));

npm run start してブラウザからhttp://localhost:3000/users/1すると確認することができます。

その他 GitHub - typestack/routing-controllers: Create structured, declarative and beautifully organized class-based controllers with heavy decorators usage in Express / Koa using TypeScript and Routing Controllers Framework. に詳しく書いてあります。


後半が雑になってしまいましたが。これくらいからドキュメントを読んでいけばサクサクすすめられそうです。typeORM + routing-controllers はシンプルで気にいったので、しばらく使ってみようと思います。

参考

18
19
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
18
19