Node.js/Express/routing-controllers+TypeScriptでWeb API作成

# はじめに

[Node.js/Express+TypeScriptでWeb API作成](https://qiita.com/honda28/items/9b0410ecbb1951fd6b00)という記事で、シンプルな Web API を作成してみた。そこではリクエストに対して定型文を返すだけであったが、最終的には PostgreSQL との接続をしてリクエストに応じた適切なデータを返す Web API 作成を考えている。しかし、Express の理解が浅いまま領域を広げるとかえって時間がかかるため、まず Express 単体で見通しをよくしていく。
本記事では、[Node.jsでも綺麗なコードでWebAPIを作る（routing-controllers）](https://qiita.com/tonio0720/items/4694d33b20d05c25c2bf)を参考に **routing-controllers** という Express 対応のパッケージを使用することで、コントローラをクラスで設計した。実行環境は以下。

- Node.js: 14.17.6
- npm: 6.14.15
- Express: 4.17.1
- TypeScript: 4.4.3
- routing-controllers: 0.9.0

(2021/9/16 追記)
Node.js のバックエンドフレームワークとしては [NestJS](https://docs.nestjs.com/) がよく用いられているらしい。NestJS は Express をコアにしていて、かつAngular の影響を強く受けているとのこと。

> Nest provides an out-of-the-box application architecture which allows developers and teams to create highly testable, scalable, loosely coupled, and easily maintainable applications. **The architecture is heavily inspired by Angular.**

機能が多岐に渡り、基本的なコントローラの書き方自体も今回扱った routing-controllers に近い。（コード例は記事末尾に記載）
今回検討した Express/routing-controllers よりも NestJS を使用した方がよいのかもしれない。

# インストールおよび tsconfig.json の設定

[routing-controllers](https://github.com/typestack/routing-controllers) を参考にインストールしていく。

```bash
$ npm install routing-controllers
$ npm install reflect-metadata
$ npm install express body-parser multer
$ npm install -D @types/express @types/body-parser @types/multer
$ npm install class-transformer class-validator
```

さらに [routing-controllers](https://github.com/typestack/routing-controllers) にしたがって、`tsconfig.json` を修正する。以降のコードではデコレータを使用しているが、デコレータは JavaScript ではまだ承認されていない機能であるためこのような設定が必要であるようだ。

```json:tsconfig.json
{
  ...
  "emitDecoratorMetadata": true,
  "experimentalDecorators": true,
  ...
}
```

# Simple Example

[Node.js/Express+TypeScriptでWeb API作成](https://qiita.com/honda28/items/9b0410ecbb1951fd6b00)と同様に `Hello World!` と返す API を routing-controllers を用いて作成すると以下のようになる。`simpleController.ts` では、コントローラをクラスで設計されており、メソッドをハンドラとして定義し、メソッドデコレータを用いてルートを指定している。

```typescript:simpleControllers.ts
import { Controller, Get } from 'routing-controllers';

@Controller()
export class SimpleController {

  @Get('/')
  helloWorld() {
    return 'Hello World!';
  }
}
```

`app.ts` では上記で作成した SimpleController をコントローラとして指定した express インスタンスを作成して実行している。

```typescript:app.ts
import { createExpressServer } from 'routing-controllers';
import { SimpleController } from './controllers/simpleController';

const app = createExpressServer({
  controllers: [SimpleController]
});
const port = 3000;

app.listen(port, () => {
  console.log(`Example app listening at http://localhost:${port}`);
});
```

routing-controllers を用いることで、API を増やす場合もコントローラごとにクラスを作成しクラス内にメソッドを追加・express インスタンス作成時にコントローラを指定するだけでよくなる。非常に見通しよくわかりやすいものとできる。

また本記事では用いていないが、Json の扱いやバリデーション、パラメータの使用なども容易に行える。詳細は [routing-controllers](https://github.com/typestack/routing-controllers) を参照。

# おわりに

routing-controllers を用いて Express の見通しよい設計を行うことができた。以降 DB 連携を試していく。[TypeORMはNode.js開発のスタンダードになるか？](https://qiita.com/tejitak/items/b6965380afd600db6513)という記事によると、DB を扱う ORM の中で TypeORM を勧めており、これを参考に TypeORM + PostgreSQL を使用して自分の作成したい Web API がうまく作成できるか試したい。

(2021/9/16 追記)
[Controllers | NestJS](https://docs.nestjs.com/controllers) に載っていた NestJS でのコントローラクラスのコード例が以下。今回紹介した routing-controllers とほとんど同じ書き方となっている。

```typescript:cats.controller.ts
import { Controller, Get } from '@nestjs/common';

@Controller('cats')
export class CatsController {
  @Get()
  findAll(): string {
    return 'This action returns all cats';
  }
}
```