OpenAPI(Swagger)を利用してTypeScriptのAPI Clientを自動生成する設計と実装
2020/11/10
累計閲覧数 10107 PV
手前味噌ではありますが、自作したTypeScript Code Generatorの記事も参照してみてください。 OpenAPIのenumがUnionTypeで吐き出されないなど、細かい問題を解決しています。
WEB
でなくても良い。
簡単な例として、/api/article
という記事を作成するAPIに対して、POST Methodで通信するとき、Request/ResponseのInterfaceを次のように定義する。
interface RequestBody {
title: string
body: string
}
interface ResponseBody {
id: string;
}
これをOASで書き起こすと次のようになる。
paths:
/api/article:
post:
operationId: createArticle # コード自動生成時の関数名となる
summary: 記事を作成するAPI
requestBody:
content:
application/json:
schema:
type: object
additionalProperties: false # Objectの拡張を許さない
required: # requiredがないObjectのValueはOptional[?]扱いになる
- title
- body
properties:
title:
type: string
body:
type: string
responses:
200: # HTTP Status Code
description: 記事が正常に作成された
content:
application/json:
schema:
type: object
additionalProperties: false
required:
- id
properties:
id:
type: number
description: 記事のID
schema
の部分がデータの定義で、それ以外はHTTP通信や説明などに関する情報を記述する。
何度も書くとドキュメントを見なくても勝手にかけてしまうので恐れることはない。
OASから実装に変換するフロートで、もっともシンプルなのは単純に変換することである。
OAS(yaml/json) --> TypeScript/JavaScript...etc
しかしながら、これだけでは実用に耐えられない。 APIのエンドポイントは複数合ったり、JavaScriptのライブラリとして提供するための体裁を整えたり、ドキュメントを出力するなど必要とされる状況やモノが多くある。
整理すると次のとおりだ。
昨今はクライアントに対して1つのAPIエンドポイントになることはほとんどない。
api1.example.com, api2.example.com, ...etc
といった具合に使う場面はスケールしていくことを考慮する必要がある。
呼応して、APIのMock Serverもドメイン単位で構築されたほうが良いだろう。
.d.ts
)とJavaScriptのコードが吐き出されることこれらを整理して考案したビルドパイプラインを次に示す。詳細は後に説明する。
ドメインがスケールできるように対応するために次のような構造をとった。
openapi-specification
├── CHANGELOG.md
├── LICENSE
├── README.md
├── docs # ドキュメントを生成場所
│ └── endpoints
│ └── api.example.com.json # OASのYAMLを1つのJSONにまとめたもの
├── endpoints # OASを記述する場所
│ ├── api.example.com # ドメイン単位でディレクトリを分ける
│ │ └── index.yml
│ └── api2.example.com # ドメイン単位でディレクトリを分ける
│ └── index.yml
├── lerna.json
├── lib # JavaScriptライブラリの生成場所
├── package.json
├── scripts # ビルド関連のスクリプトを配置
├── source # TypeScriptの生成場所
├── tsconfig.build.json
├── tsconfig.cjs.json
├── tsconfig.esm.json
├── tsconfig.json
└── yarn.lock
概略的な図を示すと次のようになる。
詳細を書く前にまずは技術選定から説明する必要がある。
技術選定
OpenAPI SpecificationからTypeScriptのコードと、ドキュメントを生成するためのツールとして利用したものは次の4つ。
今回選ばなかったもの
パイプラインの説明
技術選定の内容を再度書き下す形式になってしまうが、次のように構成されている。
TypeScriptとドキュメントの生成
endpoints/{domain}/index.yml
をビルドのエントリーファイルとする@apidevtools/swagger-cli
を用いて、エントリーファイルをdocs/endpoints/{domain}.json
にOAS 3.0のJSONに変換するapi-spec-converter
を用いてOAS3.0をSwagger 2系に変換するswagger-typescript-codegen
に与えることでTypeScriptの実装をsource/{domain}.ts
として出力するMock Serverの起動
yarn run mock:server {domain}
これらの設計を実装に落としたサンプルは以下のリポジトリにあります。
今回利用したswagger-typescript-codegen
は万能ではありません。
OASのoneOf
などのTypeScriptのUnion型で表現することが難しい場面もあります。
そのため、API Clientを自前で書く必要はなくなったが、コードジェネレーターをメンテナンスする必要は出てきます。