【NestJS】ガチ入門【その１：NestJSの概要とプロジェクト作成・立ち上げ】

# はじめに

個人開発している Web アプリで、フロントエンドは Next.js で実装しているので、バックエンドも Next.js で実装しようとしたところ、ドメイン駆動設計っぽいことをやるとむしろつらみを感じるようになりました。
というわけで、ちゃんとそのあたりのエコシステムが整っていそうな NestJS を選定しました。

選定したは良いものの、 NestJS についての知識が"ガチ"でまったくないので、まずは公式ドキュメントを読んでチュートリアルをやったりして、ココに情報をまとめていこうと思います。

ちなみに公式有料チュートリアルコース($89.99)も用意されているらしいですが、今回は公式ドキュメントの方でキャッチアップしていきます。

- 公式有料チュートリアル

https://courses.nestjs.com/

- 公式ドキュメント

https://docs.nestjs.com/first-steps

今回は、 NestJS の概要から NestJS の立ち上げまでをまとめます。
次回以降は公式ドキュメントの OVERVIEW セクションを一つずつ見ていきます。

- [【NestJS】ガチ入門【その１：NestJSの概要とプロジェクト作成・立ち上げ】](https://qiita.com/togswr/items/b901dfb4418780b81bbe)
- [【NestJS】ガチ入門【その２： Controller 編】](https://qiita.com/togswr/items/536f9ce434aa3d000534)

# NestJS ってなあに？

> Nest (NestJS) is a framework for building efficient, scalable Node.js server-side applications. It uses progressive JavaScript, is built with and fully supports TypeScript (yet still enables developers to code in pure JavaScript) and combines elements of OOP (Object Oriented Programming), FP (Functional Programming), and FRP (Functional Reactive Programming).

スケーラブルな Node.js サーバーサイドアプリを効率的に構築するためのフレームワークだよ。
JavaScript を積極的に使ってるけど、 TypeScript もフルサポートしているよ。
そして、 OOP （オブジェクト指向プログラミング）、 FP （関数型プログラミング）、 FRP (関数型リアクティブプログラミング）を組み合わせて使っているよ。

https://docs.nestjs.com/

## NestJS の哲学

> In recent years, thanks to Node.js, JavaScript has become the “lingua franca” of the web for both front and backend applications. This has given rise to awesome projects like Angular, React and Vue, which improve developer productivity and enable the creation of fast, testable, and extensible frontend applications. However, while plenty of superb libraries, helpers, and tools exist for Node (and server-side JavaScript), none of them effectively solve the main problem of - Architecture.

Node.js のおかげで JavaScript がフロントエンドとバックエンドにおいて "lingua franca" (共通語）になったよ。
これによって、いろいろなめちゃくちゃ良いプロジェクトがでてきて、フロントエンド開発におけるいろいろな開発者体験が良くなったよ。
だけど、「アーキテクチャ」に関する問題を効果的に解決するものがまだないんだ。

> 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.

Nest は out-of-the-box (標準的)なアプリケーションアーキテクチャを提供して、以下の高い性質をもったアプリケーションを開発者やそのチームが作りやすいようになってるよ。
- テスト容易性
- 拡張性
- 疎結合性
- メンテナンス性

# NestJS のインストール方法

```shell-session
$ npm i -g @nestjs/cli
$ nest new project-name
```

`nest new` コマンドに `--strict` オプションをつけると、以下のフラグが有効化されます。
- `strictNullChecks`, `noImplicitAny`, `strictBindCallApply`, `forceConsistentCasingInFileNames`, `noFallthroughCasesInSwitch`

それぞれのフラグの意味の概要については以下の記事がわかりやすいので参照してみてください。

https://qiita.com/kyntk/items/9c596306495aef06dbc0

その他のオプションについては以下を参照してください。

https://docs.nestjs.com/cli/usages#nest-new

## プロジェクト立ち上げ時の `src/` 以下のファイルたち

[公式ドキュメント](https://docs.nestjs.com/first-steps#setup)にある Overview を参考にまとめます。
なお、こちらの `src/` 以下のファイルたちを含む、 `nest new` で作成されるファイル郡は以下のリポジトリから確認することができます。

https://github.com/nestjs/typescript-starter

ディレクトリ構造と概要は以下のとおりです。

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

|ファイル名|概要|
|---|---|
|[app.controller.ts](https://github.com/nestjs/typescript-starter/blob/master/src/app.controller.ts) |基本的なコントローラー。<br/>ルートが1つだけ実装されている。|
|[app.controller.spec.ts](https://github.com/nestjs/typescript-starter/blob/master/src/app.controller.spec.ts)|コントローラーの単体テスト|
|[app.module.ts](https://github.com/nestjs/typescript-starter/blob/master/src/app.module.ts)|アプリケーションのルートモジュール|
|[app.service.ts](https://github.com/nestjs/typescript-starter/blob/master/src/app.service.ts)|基本的なサービス。<br/>メソッドが1つだけ実装されている。|
|[main.ts](https://github.com/nestjs/typescript-starter/blob/master/src/main.ts)|アプリケーションのエントリファイル。<br/>Nest アプリケーションインスタンスを生成するための `NestFactory` class が使われている。|

# NestJS の立ち上げ方法

以下コマンドで、 HTTP リクエストを待ち構えるアプリケーションを立ち上げることができます。
内部的には、 `nest start` コマンドを呼び出しています。

```shell-session
$ npm run start
```

:::note note
`npm run start -- -b swc` とすると、　[SWC builder](https://docs.nestjs.com/recipes/swc) を使ってビルドを20倍速くできます。
:::

立ち上げたら `http://localhost:3000/` にアクセスすることで、 `app.contoller.ts` および `app.service.ts` で定義されているコードが実行されます。
curl で確認してみましょう。

```shell-session
$ curl http://localhost:3000/
Hello World!
```

しっかり、 [app.service.ts](https://github.com/nestjs/typescript-starter/blob/master/src/app.service.ts) で実装されている `return 'Hello World!'` が実行されています。
ではここで、 [app.service.ts](https://github.com/nestjs/typescript-starter/blob/master/src/app.service.ts) の `Hello World!` を `Hello NestJS` に変えて再度 `curl` コマンドを実行してみましょう。

```
$ curl http://localhost:3000/
Hello World!
```

結果は変わりません。
変更を監視するには以下のコマンドを実行しましょう。

```shell-session
$ npm run start:dev
```

再度、 `curl` コマンドを実行すると、 `Hello NestJS!` に変わりました！
このコマンドでは、ファイルを監視し、自動的に再コンパイル・サーバーのリロードを行います。
内部的には `nest start --watch` を呼び出しています。

開発中は `npm run start:dev` を使うとよいでしょう。

# まとめ
- NestJS はとにかく「アーキテクチャ」面で構築するアプリケーションの〇〇性を高めてくれそうです。
- `nest new` コマンドでプロジェクトを作成、 `npm run start` もしくは `npm run start:dev` でアプリケーションの立ち上げを行いました。
- `nest new` で生成される `src/` ファイル群には基本的な、コントローラー、コントローラーの単体テスト、サービス、ルートモジュール、エントリポイントの5つのファイルが含まれていました。
- `npm run start` では変更の検知をしてくれませんが、 `npm run start:dev` を使うことで変更の検知・サーバーのリロードを自動で行ってくれます。

次回は Controller についてみていきます。

# 参考URL

- NestJS 公式ドキュメント
    - https://docs.nestjs.com/first-steps
- `nestjs/typescript-starter`
    - https://github.com/nestjs/typescript-starter/
- TypeScriptでstrict trueにするとどうなるか
    - https://qiita.com/kyntk/items/9c596306495aef06dbc0