NestJS でプロジェクト作成から API ドキュメントの表示まで

Docker で Nestjs の環境を作って、SwaggerUI で API ドキュメントを表示するところまで。
Nestjs の記事なら既にあるみたいな話はあるけれども、そこは何卒。
(プロジェクト作成だけ、とかならあっても、ドキュメントのことまで同時に書いているところはなかったような)

# ソースコード
ここで作成したコード全文は Github から確認できる
https://github.com/tktcorporation/nestjs-sample/tree/create-project-and-doc

# Dockerfile 作成

```Dockerfile
FROM node:12.16.1

RUN npm i -g @nestjs/cli

ENTRYPOINT ["/bin/bash", "-c"]
```

`@nestjs/cli` だけ入れておけば良さそう。

# docker-compose 作成

```yml
version: "3"
services:
  app:
    build: .
    working_dir: /app
    volumes:
      - .:/app
    ports:
      - "3000:3000"
```

# プロジェクト作成

## new

下記のコマンドで作成できる。

```bash
$ docker-compose run --rm app "nest new --skip-git {プロジェクト名}"
```

パッケージ管理に `npm` か `yarn` を選べるので、好きな方を選ぶ。
ここでは、 `yarn` を選んだものとして進めていく。

### --skip-git について

`--skip-git` のオプションを指定すると、 `.git` 等のファイルが作成されなくなる。
今回は下記のような構成にするため、nestjs のディレクトリには `.git` を置かないようにする。

```
.
├── Dockerfile
├── README.md
├── docker-compose.yml
└── {プロジェクト名}
    ├── README.md
    ├── nest-cli.json
    ├── node_modules
    ├── package.json
    ├── src
    ├── test
    ├── tsconfig.build.json
    ├── tsconfig.json
    └── yarn.lock
```

### gitignore の追加

nestjsプロジェクト直下に `.gitignore` を作成しておく。
(`nest new` 時に `--skip-git` を指定していない場合は自動生成される)

<details><summary>.gitignore</summary><div>

```
# compiled output
/dist
/node_modules

# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
lerna-debug.log*

# OS
.DS_Store

# Tests
/coverage
/.nyc_output

# IDEs and editors
/.idea
.project
.classpath
.c9/
*.launch
.settings/
*.sublime-workspace

# IDE - VSCode
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json
```

</div></details>

## docker-compose.yml の修正

下記のように修正して、コンテナの作業ディレクトリとプロジェクトファイルが直接つなげる。

```yml
version: "3"
services:
  app:
    build: .
    working_dir: /app
    volumes:
      - ./{プロジェクト名}:/app
    ports:
      - "3000:3000"
```

# Hello World

`yarn start` で api サーバーの起動。

```bash
$ docker-compose run --rm --service-ports app "yarn start"
```

別シェルを開いてポートの確認。

```bash
$ docker-compose ps
              Name                            Command               State           Ports         
--------------------------------------------------------------------------------------------------
app_run_xxxxxxxxx   docker-entrypoint.sh nest  ...   Up      0.0.0.0:3000->3000/tcp
```

ルートにアクセスすると、レスポンスが確認できる。

```bash
$ curl 0.0.0.0:3000
Hello World!
```

参考: https://docs.nestjs.com/cli/usages

# ドキュメントの表示

## モジュール追加

必要なモジュールをいれる。

```bash
$ yarn add @nestjs/swagger swagger-ui-express
```

## main.ts

必要な記述を追加する。

```ts
import { NestFactory } from '@nestjs/core';
// 追加
import { SwaggerModule, DocumentBuilder } from '@nestjs/swagger';
import { AppModule } from './app.module';

async function bootstrap() {
    const app = await NestFactory.create(AppModule);

    // 追加
    // ----ここから----
    const options = new DocumentBuilder()
        .setTitle('Cats example')
        .setDescription('The cats API description')
        .setVersion('1.0')
        .addTag('cats')
        .build();
    const document = SwaggerModule.createDocument(app, options);
    SwaggerModule.setup('api', app, document);
    // ---- ここまで----

    await app.listen(3000);
}
bootstrap();
```

参考: https://docs.nestjs.com/recipes/swagger

## 表示してみる

```bash
docker-compose run --rm --service-ports app "yarn start"
```

`/api` にアクセスすると、ドキュメントが確認できる。

<img width="1440" alt="Screen Shot 2020-05-16 at 0.39.55.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252342/8892580c-e1be-add4-4823-4c6cb47e5fa2.png">