きり丸の技術日記

技術検証したり、資格等をここに残していきます。

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をインストールする必要があります。前職で使用していたこともあり、apimodel等の分類ごとに細かく出力してくれるのが嬉しいポイントでした。

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を使っていた時にまとめていたので、参考にしてください。

ソースコード

なし。

終わりに

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"];