TypeORM+Express.js+routing-controllers(+SQLite3)をはじめる

# はじめに

20年近くC言語&組込環境を主戦場として戦ってきました。
しかし、世の中の流れには勝てず職場では下記構成でウェブアプリの開発をしています。

- フロントエンド : React
- バックエンド : Express + Sequelize + PostgreSQL or SQLite3
- 言語 : TypeScript
- 基盤 : Node.js or Electron

**仕事の範囲を超えた学習をするためのプログラムを作るにしても Sequelize を使うのはダルすぎる...**
ということでTypeORM と routing-controllers を利用して気軽にバックエンドを書けるか調査中。
その結果を備忘録として残しておきます。
**TypeORMを始めてみるか？**という方の役に立てば幸いです。

完全にゼロからです...

## 0. 環境回り

1. お手軽に開始したいのでSQLite3を使用しています


    いつでも違うDBに載せ替えられるのがORMのメリットですよね？
    ※あとで記事にしたいと思います

2. 本記事はWindows環境でgit bashを使っています。

3. YarnとNode.jsについては別途インストールしてください。

## 1. 準備 (TypeORM + Express + SQLite3)
### ■ プロジェクトを配置するディレクトリを作成する。

```shell
$ mkdir typeorm-sqlite-express-routing-controllers
```

### ■ TypeORM のテンプレートを生成する。

```shell
# DBを変更したい場合は sqlite を変更してください
$ npx typeorm init --database sqlite --express
```

以上で SQLite3 を利用したテンプレートが生成された。

### ■ 実行してみる

```shell
$ yarn install
$ yarn start
```

上記でエラーが出ないようであれば、curl を利用して API にアクセスする。

```
$ curl http://localhost:3000/users
[{"id":1,"firstName":"Timber","lastName":"Saw","age":27},{"id":2,"firstName":"Phantom","lastName":"Assassin","age":24}]
```

JSON で結果を得られているので正常動作している事を確認できました。
*※TypeORM で生成したテンプレートを実行すると、users にデータが幾つか登録されます。*


## 2. routing-controllers を使える状態にする

### ■ パッケージを追加する

```shell
yarn add -D typeorm-routing-controllers-extensions routing-controllers
yarn add -D class-transformer class-validator
```
### ソースを修正する
#### ■ routes.ts を削除する

    routing-controllers を使うので不要。

### ■ src/index.ts を編集する

```typescript
import "reflect-metadata";
import { createConnection, useContainer } from "typeorm";
import { createExpressServer } from "routing-controllers";
import { UserController } from "./controller/UserController";

createConnection()
  .then(async (connection) => {
    console.log("Connected. ");

    const ap = createExpressServer({
      controllers: [UserController],
    });

    ap.listen(3000);

    console.log(
      "Express server has started on port 3000. Open http://localhost:3000/users to see results"
    );
  })
  .catch((error) => console.log(error));
```

### ■ controller/UserController.ts を編集する

※ json を返すバックエンドを作成するため @JsonController を使用しています。

```typescript
import {
  Param,
  Body,
  Get,
  Post,
  Put,
  Delete,
  JsonController,
  NotFoundError,
} from "routing-controllers";
import { User } from "../entity/User";
import { getRepository, Repository } from "typeorm";
import { EntityFromParam } from "typeorm-routing-controllers-extensions";

@JsonController()
export class UserController {
  userRepository: Repository<User> = getRepository(User);

  @Get("/users")
  getAll() {
    return this.userRepository.find();
  }

  @Get("/users/:id")
  async getOne(@EntityFromParam("id") user: User) {
    if (!user) {
      throw new NotFoundError("User was not found !");
    }
    return user;
  }

  @Post("/users")
  async post(@Body() user: any) {
    return await this.userRepository.save(user);
  }

  @Put("/users/:id")
  async put(@Param("id") id: number, @Body() user: any) {
    return await this.userRepository.update(id, user);
  }

  @Delete("/users/:id")
  async remove(@EntityFromParam("id") user: User) {
    if (!user) {
      throw new NotFoundError("User was not found !");
    }
    return await this.userRepository.remove(user);
  }
}
```

## 3. 動作確認

### ■ バックエンド起動

```shell
$ yarn install
$ yarn start
```

上記でエラーが出ないようであれば、curl を利用して API にアクセスする。

### ■ curl を利用してテスト

```
$ curl http://localhost:3000/users
[{"id":1,"firstName":"Timber","lastName":"Saw","age":27},{"id":2,"firstName":"Phantom","lastName":"Assassin","age":24}]
```

JSON で結果を得られているので正常動作している事を確認できました。

## 4. その他

SQLite3の保存データをgit管理する必要はないので .gitignore に database.sqlite を追加。

## 5. ソース

本記事のソースは下記から取得できます。

https://github.com/t-kawamorita/typeorm-sqlite-express-routing-controllers/releases/tag/step1