FastAPIから型定義を出力する
始めに
小ネタ。
FastAPIからopenapi.jsonが出力できるなら、フロントエンドで使用する型定義まで出力する手順を確立したくて記事にします。
なお、フロントエンドはすでに構築されていたこともあり、自動生成した型定義の導入までは行えていません。また、FastAPIから型定義を出力する際にこういう工夫をしています、というコメント募集しています。
環境
- FastAPI
- 0.115.12
- openapi-typescript
- 7.8.0
- @openapitools/openapi-generator-cli
- 2.20.2
実装
OpenAPIファイルの取得
FastAPIの/openapi.json
にアクセスするとopenapi.json
ファイルを取得できます。他の方法で出力することもできますが、これが一番簡単だと思います。
ファイルとして出力してもいいですが、そのままHTTPのままアクセスするのが手間がかからなくてオススメです。
openapi-typescript を使用する場合
一番簡単にd.tsを出力できます。人気が高いようなのでこれを利用した記事がいくつかありそうなのですが、私が想像していた直感的に欲しい型情報ではなかったです。フロントエンドはこういう使い方をするのかもしれませんが、使い方が私には分からなかったです。
bunx openapi-typescript http://localhost:8000/openapi.json -o src/types/api.d.ts
@openapitools/openapi-generator-cli を使用する場合
Javaをインストールする必要があります。前職で使用していたこともあり、api
やmodel
等の分類ごとに細かく出力してくれるのが嬉しいポイントでした。
bunx @openapitools/openapi-generator-cli generate -i http://localhost:8000/openapi.json -g typescript-angular -o src/app/openapi
JetBrainsを使用している場合はすでにjavaが含まれているのでIDE上でファイル出力できます。ただし、WSLの場合だとファイルパスがWindowsとWSLで合わないため、\と/を書き換える必要がありました。
# IDEから出力されるコマンド
# パスに関しては %USERPROFILE% で書き換えていますが、/と\はそのままです
%USERPROFILE%\AppData\Local\Programs\WebStorm\jbr\bin\java.exe -jar %USERPROFILE%/AppData/Local/JetBrains/WebStorm2025.1/openapi/codegen/d1f8bb39b5817ae983385027d47d550c/openapi-generator-cli-7.7.0.jar generate -g typescript-angular -i %USERPROFILE%\AppData\Roaming\JetBrains\WebStorm2025.1\scratches\openapi.json -o %USERPROFILE%\gen --additional-properties=
この辺のIDE経由で実行する方法については、以前Javaを使っていた時にまとめていたので、参考にしてください。
- https://nainaistar.hatenablog.com/entry/openapi-generate-by-intellij-idea
- https://nainaistar.hatenablog.com/entry/2022/10/03/120000
ソースコード
なし。
終わりに
openapi-typescript
が一番人気ということはエコシステムも揃っていそうだったのですが、サンプルの次のコードを見て便利そうには思えなかったです。フロントエンドエンジニアとしては、これが一般的なんですかね…。
OpenAPI自体はいい仕組みだと思うので、フロントエンドでうまく使う方法をもっと理解していきたいです。
# 公式のサンプルコード
# https://www.npmjs.com/package/openapi-typescript
import type { paths, components } from "./my-openapi-3-schema"; // generated by openapi-typescript
// Schema Obj
type MyType = components["schemas"]["MyType"];
// Path params
type EndpointParams = paths["/my/endpoint"]["parameters"];
// Response obj
type SuccessResponse =
paths["/my/endpoint"]["get"]["responses"][200]["content"]["application/json"]["schema"];
type ErrorResponse =
paths["/my/endpoint"]["get"]["responses"][500]["content"]["application/json"]["schema"];
Discussion