OpenAPI Generator を使って typescript-fetch のソースコードを生成してみる

OpenAPI でスキーマを書くとクライアントサイドのソースコードが自動生成できると聞いたのでやってみた。

スキーマ記述

色々とエディタもあるようだが今回は Swagger Editor を使ってスキーマを記述する。

https://editor.swagger.io/

で書けるが、私は手元で書こうと思い Docker を使った。

https://github.com/swagger-api/swagger-editor#docker

に Docker での起動について記載がある。

docker pull swaggerapi/swagger-editor
docker run -d -p 80:8080 swaggerapi/swagger-editor

デフォルトだと OpenAPI 2 系のサンプルが起動するので、エディタ上部メニューの
Edit > Convert to OpenAPI 3
で 3 系にコンバートしてからサンプルを書き換えるといいと思う。

OpenAPI Generator でクライアントサイドコード生成

ローカルにインストールするのが面倒なので、こちらも Docker を使う。

https://github.com/OpenAPITools/openapi-generator#16---docker

に記載の通り、基本コマンドは

docker run --rm -v "${PWD}:/local" openapitools/openapi-generator-cli generate \
    -i <OpenAPI のスキーマファイル> \
    -g <対象言語> \
    -o <出力先>

である。
Docker に慣れている人は間違わないと思うが、スキーマファイルと出力先はカレントディレクトリを /local に置き換えて記述したパスになるので注意。

私は今回 typescript-fetch で生成しようと思ったので、下記のドキュメントを参考にしつつ

https://openapi-generator.tech/docs/generators/typescript-fetch

次のコマンドでソースコードを生成した。

docker run --rm -v "${PWD}:/local" openapitools/openapi-generator-cli generate \
    -i /local/src/lib/openapi.yaml \
    -g typescript-fetch \
    -o /local/src/lib/api \
    --additional-properties=modelPropertyNaming=snake_case,supportsES6=true,typescriptThreePlus=true

追加したオプションは次の通り。

  • modelPropertyNaming=snake_case
    • もともと書いていたコードでスネークケースにしていたので。
  • supportES6=true
    • 現時点で必要かどうかわからないがとりあえず true にしておいた。
  • typesciptThreePlus=true
    • これを true にしないと『“GlobalFetch” が無い』みたいなエラーになる。ドキュメントによると現在のデフォルト値は true らしいが、この記事を書いた日時点での Docker での生成ではデフォルト値 false だった。

こうすると指定したディレクトリにソースコードが生成される。

生成したソースコードを使う

さて自動生成したはいいが使い方は書いていない。
もしかしたらどこかに書いてあるのかもしれないが見つからない。

下記の記事を参考にしたが、オプションによって微妙に違うかもしれないので、自分でもソースコードを読んで使い方を把握する必要がある。

OpenAPI Generator typescript-fetch を使う

私が今回作った API の名前は BlogsApi だったので、インスタンス生成はこうなる。API のパスは環境変数を設定しているのでそれを呼び出している。

import { BlogsApi, Configuration } from 'src/lib/api/index'

const conf = new Configuration({
  basePath: process.env.REACT_APP_API_BASE_URL,
})
const blogsApi = new BlogsApi(conf)

あとは生成したソースコードを見つつ API 呼び出しメソッドを呼べばいいが……。

呼び出した結果、TypeScript のエラーとなって使えなかった。

該当部分のソースは

(json['data'] as Array<any>).map(JsonToModel)

みたいな感じで、出ていたエラーは『json.data.map is not a function』であった。

私が実装したバックエンドの API が間違っているのかと思ったが、私は既存実装にて json[‘data’] にあたる部分を配列として扱い map 処理も行っているし、レスポンスをコンソールに書き出しても json[‘data’] は確かに配列に見える。
自分の TypeScript/JavaScript 力ではこの該当部分のコードでなぜエラーが起こるのかわからなかった。

そのため、使えそうなら既存実装を置き換えようと思ったのだが、結局生成したコードを使用するには至らなかった。

以上