OpenAPI TypeScript Code GeneratorをASTを利用して作成しました
CHANGELOG
$ref
は使えません。operationId
のみを選択できるようにオプションを追加しました。例4
を修正。有名なシステムやライブラリのOpenAPIから生成したTypeScriptのサンプルコードのリポジトリを追加しました。OpenAPI Specification(以下 OAS)からTypeScriptのコードを生成するためにはいくつかのライブラリが存在したので最初はこれらを使ってみました。
しかしながら、複雑度が増すとうまく機能しない点が出てきました。
OASがシンプルなうちは小回りが効くので良かったのですが、分割したファイル数が50を超え、 それらが一つの型定義に集約されるとその型定義がとても使いづらくなる問題が発生しました。
また、特定のライブラリに依存したAPI Clientを生成するものがほとんどで、実際のプロジェクトに導入するときの明らかな障害になります。 fetchで統一してるのに、axiosいれる?とかその逆も然り。
さらに、自作のテンプレートが書けるとのことで実際に書いてみると、API Clientの部分的な変更や、Mustash記法などさまざまな形式で提供されているのでこれに対する学習コストが高く、保守コストの観点から流布させるのが困難でした。
このため、拡張性がしやすくTypeScriptユーザーが保守しやすいジェネレーターを作ろう、というのが今回のモチベーションです。
GitHubのREADMEにも書いてますが、以下を指針としてライブラリを設計して開発しました、
.js
に変換したとき、ファイルサイズが 0 になること)これを実現させるために、TypeScript ASTをフルに利用してCode Generatorを作成しました。
TypeScript ASTを利用すると、oneOf
やallOf
を共用型と交差型に変換することも(かなり)容易でした。
また、ディレクトリ構造をnamespace
へと変換し、その構造を型定義の構造へ写像することによって参照構造がかなり明確になりました。
この参照解決の実装に関してはかなり労力を割いて作ったので、ぜひ試してほしい機能の一つです。
2つほど例を示しておきます。実際に使ってみると威力がわかるかと思います。 (すくなくとも記事中で説明すると半端ない量になるのでドキュメント化すると心が折れます)
oneOf
の例# spec.yml components: schemas: OneOfType: oneOf: - type: string - type: number - type: object
変換後
export namespace Schemas { export type OneOfType = string | number | {}; }
# spec.yml components: schemas: RemoteRefString: $ref: "./components/schemas/Level1/RemoteBoolean.yml"
# ./components/schemas/Level1/RemoteBoolean.yml type: boolean
変換後
export namespace Schemas { export namespace Level1 { export type RemoteBoolean = boolean; } export type RemoteRefBoolean = Schemas.Level1.RemoteBoolean; }
PlayGroundに書きました。
※ DockerのOpenAPIに関しては、unixソケット経由での通信になるため、node-fetch
などではCallできないため、自前でRequestを書く必要があります(Source)。
ディレクトリ構造を実装に落とし込むことによって制限が生じています。 TypeScriptのnamespaceの宣言名で利用できるものしかディレクトリ名に利用できなくなります。 この点の自由度はマイナスポイントですが、名前空間を受動的に整理される利点があります。
もしかしたら、TypeScript内で利用できない命名はvalidationで弾いたり、camelCaseに変換するなど、内部実装を柔軟に変更する方法もあるかもしれません。
追記: -|/|_
が含まれている場合自動的に$
に変換するようになりました。
ほかにも制限があるので、気になる人はREAMDEを見てみてください。
TypeScript ASTを利用してコードを拡張できるようにしています。一見すると難しいのですが、ts-ast-viewerというとても優秀なツールを利用することで、ASTの利点を瞬時に享受することができます。
出力する言語の実装を、同じ言語で変更できるので学習コストが低く、ts-ast-viewerのようなPlaygroundがあることで最初の第一歩が踏み出しやすく、拡張の自由度が担保できていると考えています。
デフォルトのAPI Templateは依存関係の注入を行う様になっています。 また、QueryParmaeterのフォーマットも外側で行うようにしており、実質的な処理が記述されていません。 Parameter系はさまざまなフォーマットがあり、これに関しては別のライブラリとして切り出しています。
サンプルプロジェクトにこれらの使い方が書いてあるので、ぜひ見てください。
(2022/03/21更新)
いくつかのメジャーなシステムのOpenAPI Schemaを生成することができるようになってきました。 今後は使い勝手と精度を上げていこうと考えています。バグなどあればぜひPull Requestを投げてください。
リポジトリにスターを付けるとモチベーションが大変上がります。