🐧

OpenAPIの分割された定義ファイルからコードを生成する

2023/03/09に公開

デザインエンジニアのりょーたです。
弊社では、フォロワー採用サービスのMusubiteというプロダクトを開発しています。

フロントエンドをNext.js(SSR)、バックエンドをRuby on Railsで開発しており、データのやり取りはREST APIを用いています。REST APIの仕様は、OpenAPIを導入して管理をしており、フロントエンドでは、そのスキーマを用いてソースコードの生成を行なっています。

今回の記事では、aspida用の型定義を作成できるようになるまでのプロセスをまとめようと思います。

前提として、OpenAPIの定義ファイルは、以下のようにymlファイルを役割ごとに分割をして管理しています。

$ tree -L 2                                                              
.
├── README.md
└── openapi
    ├── components
        ├── xxx.yml
	└── xxx.yml
    ├── index.yml
    ├── paths
        ├── xxx.yml
	└── xxx.yml
    └── swagger.yml

そのため、定義ファイルを1つに結合してから、コードの自動生成を行いました。

【1】ymlファイルの結合

定義ファイルが参照を用いて分割されているので、swagger-mergerというライブラリを使用して1つにまとめます。

https://www.npmjs.com/package/swagger-merger

今回のケースでは、結合した上でjsonファイルとして出力させたかったので、以下のようにしました。

npx swagger-merger -i [ファイルパス] -o swagger.json

【2】出力したjsonファイルからスキーマの生成

次に、コードの生成を行います。
今回は、HTTPクライアントライブラリとしてaspidaを導入するため、aspida用の型定義作成にopenapi2aspidaというライブラリを採用しました。

https://github.com/aspida/openapi2aspida

上記のドキュメントを参考にすると問題なくできるかと思います。
実際にプロジェクトで実行したコマンドは以下の通りです。

# 生成後のディレクトリ作成
mkdir api
# 設定ファイル作成(設定内容は下記参照)
vim aspida.config.js
# 生成
npx openapi2aspida
aspida.config.js
module.exports = {
  input: 'api',
  outputEachDir: true,
  openapi: { inputFile: 'swagger.json' },
};

普段は1つずつ実行するのは面倒なので、以下のようにしてシェルスクリプトを用意し、自前のnpmスクリプトから実行するようにしています。

scripts/generateApi.sh
# 実行時は各自のパスに置き換えてください
PATH="../linkful-mock/openapi/index.yml"
FILE=swagger.json
if [ -f $PATH ]; then
    npx swagger-merger -i $PATH -o $FILE
    echo '✅  create swagger.json'
    rm -rf api/*
    npx openapi2aspida
    yarn build:api
    echo '✅  build api scheme'
    rm $FILE
    echo '🎉  complete jobs!!'
else
    echo -e "❌ ファイル(FILE)のパスを書き換えてください"
fi
package.json
{
  "scripts": {
    "build:api": "aspida",
    "generate:api": "bash scripts/generateApi.sh"
  }
}

更新を行う際、すでにapi/にファイルがあれば更新されなかったため、毎回削除して入れ直すするようにしたのですが、どうにも釈然としない、、
解決方法をご存知の方は教えていただけると助かります🥲

最後に

今回、1人目デザイナー、1人目フロントエンドエンジニアとしてMVPリリースに携わったのですが、学びあり妥協ありでとても濃い経験ができました!
ご興味を持った方はぜひお気軽にお話ししましょう🥳

https://musubite-job.com/recruitments/XYqiNX?utm_source=zenn

Discussion