序
いろいろと前提を書き連ねますが、読むのが面倒な人は本まで飛んでください!
記事内容について
この記事は「筆者(orifuji)がopenapi3-tsを試してみるシリーズ」の最初の投稿となります
今回は主にライブラリの仕様調査、およびOAS自体の説明を行います
これで脱稿とするよりも、知見の増加・認識の更新に合わせてしばらくは編集を続けようと思っています
次回は実際に使ってみて、OpenAPI Specificationに則ったjsonないしyamlなファイルをアウトプットするところまでを扱います
最終的には、わたし自身のユースケースに沿ったラッパーライブラリを実装します
筆者の属性
TS初心者
会社のプロダクトではTSがWeb Frontendに採用されています
ただ、自分はServerメインのため知見はさほどないです
OpenAPI Specification知識はある
前職で新規プロジェクト開発に際して導入作業を一部行いました
筆者のTS学習も兼ねているため、言語仕様に知悉している方からすると冗長な記述が目立つかもしれません
そもそもOpenAPI Specificationとはなにか
OpenAPI Specification(OAS)は、実装(プログラミング言語等々)に依存しないinterface定義のためのWeb API仕様記述フォーマットです
OASはyamlまたはjsonで表現できるように構造化された仕様になっています
仕様の表現それ自体とは別に得られる恩恵として
ドキュメント生成ツール
コード生成ツール
テストツール
(OASを読み込んでレスポンスを生成する)スタブサーバーツール
などのような、OAS準拠のサードパーティツール群の恩恵に与れることが挙げられます
なお、上記説明は公式の記述をもとに、自分の言葉に置き換えたものです
なぜOASファイルをプログラムから生成するのか
ざっくり下記のようなメリットがあるかと思います
API定義ファイルがプログラマブルな対象になると、API定義ファイル内の共通化や(一本ファイルへ統合するための)ビルドなどが容易になる
OAS自体はファイル分割に対応した仕様ですが、クライアントツールが追従していない場合もあるため、分割→再統合のためのシステムを自前で組むことになりがち
プログラムで書く場合、プログラム内で分割や共通化を扱っておいて、それをファイル生成時に一本化するだけなので、上記のようなシステムの構成をあまり気にしなくて良くなる
(開発言語選定次第では)強力な静的解析・補完の恩恵に与れる
対してデメリットは
stoplight studioなどのOASをターゲットとしたエディタのパワフルな機能に頼れなくなる
ある程度、自力でOASに詳しくなる必要が出てきます
TSの選定理由
だいたいこのような理由を総合して、とりあえず試しにTypeScriptでやってみようかなと決めました
ライブラリ(openapi3-ts)を見つけた
静的型付け言語である
VSCode上で簡単に扱える
Web Frontendを中心に、TS経験のある開発者の人口が多い
特に自分の場合は、プロダクトチーム内のほとんどの開発者が扱えるため、TSを選びました
チームで実際に採用するかは分かりませんが、巻き込める状況が大事かなと思ってのことです
わたし自身がTSに慣れ親しみたい
ちなみに、OAS - TSの組み合わせのベネフィットに関しては夕暮おこはさんの記事が最高にわかりやすいです!
Acknowledgment
@suin さんの下記リポジトリを実用事例として参考にしました
仕様把握・コードリーディングに際して、めちゃくちゃ助かりました
感謝しております
本
以下では、openapi3-tsの仕様の概観を述べます
概要
openapi3-tsは、最新のOASの仕様に準拠しているライブラリで、下記が特徴です
OASの各種コンポーネントを、TypeScriptの型として表現している
それらを用いつつ、実体としてのOASを組み上げるためのAPIを提供している
提供されているクラス・interface
ライブラリのディレクトリ構造に、簡潔に表現されています
下記の二つのサブディレクトリが存在して、それぞれの責務は次に付記する通りです
src/model
OpenAPI SpecificationをTypeScriptの型定義で表現するためのinterface群
src/dsl
上記モデルをインスタンス化するための操作を、DSL(domain-specific language)的に実装したBuilderクラス
src/index.tsで、ライブラリが公開するfunction, class, interfaceなどがexportされています
基本的にこれを使う側で拾ってあげれば良いかと思います
How to use
ライブラリ本体に現状Docがないので、簡単にHow to useを整理したいと思います
わたし個人のメモ程度の代物であることを念頭にお読みいただければさいわいです
How to install
為念
npm管理できるので、npm installやyarn addでプロジェクトに導入しましょう
OASの構造と対応したパーツをひとつひとつ作ってゆく
まずは個別のendpoint = pathを作ったり、共通部分(汎用的なヘッダやレスポンスボディ構造など)を括り出したりしてゆきます
以下はイメージを掴んでもらうための疑似コードです
ランタイムでの動作を確認していません
次回以後、実際に動作するコードを書きますのでお待ちください。また、こちらも適宜修正してゆきます
const tag_todos: TagObject = {
description: "TODOに関するエンドポイント",
"x-displayName": "TODO",
},
const schema_todos_200: SchemaObject = {
// 長くなるためいったん省略(あとでそれらしいコードにしておきます)
}
// このPathItemObjectが個別のエンドポイントの仕様定義になります
const path_todos: PathItemObject = {
get: {
summary: "やること一覧を取得する",
operationId: "get-todos",
tags: [tag_todos],
responses: {
"200": schema_todos_200,
},
},
};
OpenApiBuilderで、OASに準拠した構造のオブジェクトをインスタンス化する
Builderにそれぞれのパーツを渡し、OAS全体を作り上げてゆきます
// 予めoas_builderを初期化している想定で書いています
// getSpec()はOpenApiBuilderのメンバーを元に、OAS準拠のオブジェクトを返却します
const oas: OpenAPIObject = oas_builder.addPath(path_todos).getSpec();
インスタンスを別のプログラムに渡してあげる
例えば、jsonファイルの出力を行うモジュールに渡してあげます
// それをjson形式に変換して
const output_json: string = JSON.stringify(oas);
// ここでは新規ファイル作成用に作っておいたラッパー関数に渡す想定で書いています
writeNewFile("./docs/oas_my_todo_app.json", output_json);
結
openapi3-tsの概観は掴めたかなと思います
次回からは、実用に入ります
簡単なAPI定義を想定しつつ、↓のようなことをしてみようかなと思います
愚直にTSで仕様書を組む
使いやすくするために、ライブラリをラップし、拡張的な操作を加えてゆく
前回:-
次回:
↧