BLOG

ブログ

NestJS×Swagger×Amplify | API仕様書をホスティング

こんにばちんわ。
最近は色々な業務を担当しております、ともきです。
ワールドカップ熱も徐々に冷め、サッカー人気が絶えず続くことを願う日々であります。

今回は、NestJSのSwagger(OpenAPI)定義をyamlファイルに出力し、AWS Amplifyでホスティングします。(圧倒的シンプル

ざっくりイメージ


※この記事ではNestJSについて、Swagger(OpenAPI)についてなどの解説はいたしません。
気になる方は【NestJS公式】をご確認ください。
(個人的にNestJSの公式ドキュメントはかなり充実していると感じてます)

それではさっそく参りましょう!

目次

動作環境とライブラリ

node18.13.0
yarn1.22.19
@nestjs/cli9.1.8
@nestjs/swagger6.1.4
swagger-ui-dist4.15.5
@nestjs/mapped-types1.2.0
js-yaml4.1.0
@types/js-yaml4.0.5
動作環境

NestJS CLIでプロジェクト作成

NestJSには、便利なCLIが備わっていますので活用しましょう。
「open-api-hosting」は今回のプロジェクト名です。

nest n open-api-hosting

【NestJS公式】CLI command reference

何のパッケージマネージャーを使用するか質問されます。
私はいつもyarnを使用しているので、yarnを選択します。

⚡  We will scaffold your app in a few seconds..

? Which package manager would you ❤️  to use?
npm
❯ yarn
pnpm

初期プロジェクトとしてファイルなどが生成されますので、移動して以下の形式になっていることを確認します。

生成されたものたち

無事雛形を確認できたので、一度起動確認もします。
(プロジェクトルートに移動して実行)

yarn start:dev
起動確認

大丈夫そうですね!
デフォルトでTypescriptがサポートされていて、eslintやprettier、テストファイルなどの雛形作成もしてくれているので大変助かります。
これでNestJSの雛形プロジェクトの作成は完了です。

Swagger(OpenAPI)のインストールと設定

@nestjs/swaggerインストール

yarn add @nestjs/swagger

main.tsを編集

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

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  // ■■■■■■■追記■■■■■■■
  const config = new DocumentBuilder()
    .setTitle('NestJS Amplify Hosting')
    .setDescription('説明')
    .setVersion('1.0.0')
    .build();
  const document = SwaggerModule.createDocument(app, config);
  // 第一引数はpathとなります。任意のパス可
  SwaggerModule.setup('swagger', app, document);
  // ■■■■■■■追記■■■■■■■
  await app.listen(3000);
}
bootstrap();

Swagger(OpenAPI)の起動確認

yarn start:devで起動し、http://localhost:3000/swaggerにアクセスして表示されていることを確認します。

swagger-ui起動確認

yamlファイルとして出力しよう

必要ライブラリインストール

yaml ファイルを読み書きするライブラリをインストールします。
念の為、型定義ファイルもインストールしましょう。

yarn add -D js-yaml @types/js-yaml

main.tsの編集

import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger';
// ■■■■■■■追記■■■■■■■
import * as fs from 'fs';
import { dump } from 'js-yaml';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  const config = new DocumentBuilder()
    .setTitle('NestJS Amplify Hosting')
    .setDescription('説明')
    .setVersion('1.0.0')
    .build();
  const document = SwaggerModule.createDocument(app, config);
  // 第一引数はpathとなります。任意のパス可
  SwaggerModule.setup('swagger', app, document);
  // ■■■■■■■追記■■■■■■■
  fs.writeFileSync('src/docs/swagger.yml', dump(document, {}));
  // ■■■■■■■追記■■■■■■■
  await app.listen(3000);
}
bootstrap();

docsフォルダとswagger.ymlファイルを作成しましょう。

mkdir src/docs;touch src/docs/swagger.yml

再起動して、yamlファイルが生成されていることが確認できます。

yaml確認

yamlファイルをhtml変換してブラウザで表示する

「node_modules/swagger-ui-dist/」をコピー

swagger-uiのテンプレートがnode_modulesにあるので、ごっそりと「src/docs」にコピーします。

cp node_modules/swagger-ui-dist/* src/docs

コピーしてきたファイルがたくさんありますが、修正箇所は一箇所のみなので安心してください。

swagger-ui-dist/

swagger-initializer.jsの編集

window.onload = function () {
  //<editor-fold desc="Changeable Configuration Block">

  // the following lines will be replaced by docker/configurator, when it runs in a docker-container
  window.ui = SwaggerUIBundle({
    // 出力したyamlに置き換え
    // url: "https://petstore.swagger.io/v2/swagger.json",
    url: './swagger.yml',
    dom_id: '#swagger-ui',
    deepLinking: true,
    presets: [SwaggerUIBundle.presets.apis, SwaggerUIStandalonePreset],
    plugins: [SwaggerUIBundle.plugins.DownloadUrl],
    layout: 'StandaloneLayout',
  });

  //</editor-fold>
};

LiveServerで動作確認

VSCodeの拡張機能LiveServerを使用して、「src/docs/index.html」の表示を確認してみます。

LiveServerで確認

設定内容が反映されていることが確認できました。
index.css」で画面の表示項目など編集できるので、遊びがてらカスタマイズしてみてください。
(swagger-uiのテンプレートに合わせたほうが見やすい気がする。。。)

Amplifyでホスティングしてみる

※Github連携の箇所は割愛します

リポジトリブランチの追加

  • リポジトリの選択
  • ブランチの選択
  • monorepoチェックボックス選択
  • 対象のディレクトリ入力(今回は→src/docs
setting

ビルド設定

「AWS Amplifyがプロジェクトのルートディレクトリで…」にチェック入れる。
特にすることもないので、「次へ」を選択し、デプロイ終わるまで待機します。

デプロイ終了&確認

ドメインの箇所をクリックして、ホスティングされているか確認します。

waiting…

OKですね!

complete!

Basic認証やカスタムドメインを設定したりすることもできます。

最後に

最後まで、お付き合いいただきありがとうございます。
yamlファイルからhtmlの変換は色々な方法があります。
RedocをDocker環境で使用して作成する方法などが主流?なのかもしれませんが、今回は手早くシンプルな方法をご紹介しました。
NestJSでSwaggerを使用する際はアノテーション地獄に気をつけたいですね。

Twitterフォローお願いします⭐

参考文献