OpenAPIファイルは、APIの信頼できる唯一の情報源です。そこにはすべてのパス、すべてのパラメーター、すべてのレスポンスの形式がリストされています。しかし、チームのほとんど誰も生のYAMLやJSONを読みたがりません。バックエンドエンジニアはリポジトリ内の簡単なエンドポイントリファレンスを欲しがり、フロントエンド開発者はプルリクエストでスキャンできるリクエストフィールドの表を欲しがります。テクニカルライターは、スキーマ全体を再入力せずにWikiに貼り付けられるものを欲しがります。
Markdownは、これらすべての読者に適した形式です。GitHub、Confluence、静的サイトジェネレーター、そしてプレーンテキストエディターでもレンダリングされます。したがって、繰り返し発生するタスクは、既存のopenapi.yamlを、人間が実際に開くクリーンなMarkdownに変換することです。手作業で行うのは遅く、誰かがエンドポイントを追加した瞬間にずれてしまいます。自動的に行うことだけが、実際のリリースサイクルと接触しても生き残る唯一のバージョンです。
OpenAPIからMarkdownを生成する理由
OpenAPIドキュメントはマシン向けに作られています。ツールはそれをパースしてクライアントを生成し、契約テストを実行し、リクエストを検証し、インタラクティブなドキュメントをレンダリングします。マシンが読み取れることが全体的なポイントであり、それを保護する価値があります。仕様自体を正確に保つことについて復習したい場合は、OpenAPIバリデーターツールのガイドで、何かを生成する前にリンティングを行うことについて説明しています。
Markdownは異なる問題を解決します。それは、OpenAPIレンダラーが実行されていない場所で人間に配布することです。いくつかの具体的なケースが繰り返し発生します。
- リポジトリ内の
README.mdまたは/docsフォルダー。新しい貢献者がコードベースを離れることなくエンドポイントリストを見られるようにします。 - 新しいエンドポイントが受け入れるものと返すものを示す必要があるプルリクエストの説明。
- 非エンジニアを含む広範なチームが契約をレビューするConfluenceまたはNotionページ。
- Docusaurus、MkDocs、またはHugoで構築された静的ドキュメントサイト。これらはすべてMarkdownを入力として受け取ります。
重要なキーワードは「自動的に」です。一度書いて忘れたMarkdownファイルは、次のスプリントでは間違ったものになります。変更があるたびに仕様から再生成されるMarkdownファイルは、無料で契約に忠実であり続けます。それが、人々が信頼するドキュメントと、人々が無視するようになるドキュメントとの違いです。
変換方法:手軽なものから堅牢なものまで
OpenAPIに同梱されているMarkdownを生成するための単一の公式コマンドはありません。代わりに、少数のコンバーターエコシステムと、APIプラットフォームに組み込まれたドキュメントエンジンがあります。以下に、それぞれに要する設定の量に基づいておおよそ並べられた状況を示します。
| 方法 | 最適 | 得られる出力 |
|---|---|---|
openapi-to-md / openapi-markdown |
高速で設定不要なMarkdownダンプ | 単一のMarkdownファイルまたはスキーマテーブル |
| Widdershins | コードタブ付きのSlate/Docusaurusスタイルのドキュメント | 言語サンプル付きのテーマ可能なMarkdown |
| パース済み仕様に対するカスタムスクリプト | チームが求める正確なレイアウト | テンプレート化したものすべて |
| Apidog | 仕様のインポート、レンダリングされたドキュメント、テストを1つのワークスペースで | ホストされたドキュメントとMarkdownコンテンツブロック |
どれだけの制御が必要か、そして出力がどこに置かれる必要があるかに基づいて選択してください。次のセクションでは、それぞれの実行方法を示します。
方法1:ワンラインのオープンソースコンバーター
最も速い方法は、専用のコンバーターを使うことです。NodeとPythonの世界では、2つのよく知られたものがあります。
Nodeプロジェクトの場合、openapi-to-mdはYAMLまたはJSON形式のv2またはv3ドキュメントを受け取り、構造化されたMarkdownファイルを作成します。グローバルインストールなしで実行できます。
npx openapi-to-md openapi.yaml api-reference.md
Pythonツールチェーンの場合、openapi-markdownはpipインストールと単一のコマンドで同じ仕事をします。
pip install openapi-markdown
openapi2markdown openapi.yaml api-reference.md
どちらも仕様を読み込み、すべてのパスとスキーマをウォークし、エンドポイントごとの見出しとパラメーターとレスポンスのテーブルを含む1つのMarkdownファイルを出力します。これらのツールの中には出力ファイル引数がオプションのものもあります。省略すると、入力名に.md拡張子が付いたものがデフォルトになります。これは、必要に応じて再生成するリポジトリリファレンスには十分です。
高速コンバーターのトレードオフは、レイアウトの制御です。自分の構造ではなく、それらの構造が得られます。デフォルトのテーブルがチームのドキュメントの読み方と一致していれば、ワンラインで完了です。5つの言語でコードサンプルが必要な場合や、特定のセクションの順序が必要な場合は、次の方法が必要になります。
方法2:コードサンプル付きのテーマ可能なドキュメントのためのWiddershins
Widdershinsは、OpenAPIまたはSwaggerファイルをSlate互換のMarkdownに変換するための確立されたNodeツールです。言語コードタブとカスタマイズ可能なテンプレートが必要な場合、およびMarkdownがDocusaurusやMkDocsのような静的サイトジェネレーターに供給される場合に役立ちます。
インストールして基本的な変換を実行します。
npm install -g widdershins
widdershins openapi.yaml -o api-reference.md
出力先が独自のヘッダーを追加する場合、コードサンプルの言語を追加し、フロントマターヘッダーを削除します。
widdershins --language_tabs 'shell:cURL' 'python:Python' 'javascript:JavaScript' \
--omitHeader openapi.yaml -o api-reference.md
Widdershinsはテンプレートシステムを使用しているため、デフォルトを受け入れる代わりに、任意のセクションのレイアウトをオーバーライドできます。これにより、生のダンプと完全に手作業で構築されたドキュメントサイトとの間の橋渡しとなります。コストは、テンプレートとビルドステップを管理する必要があることです。これはドキュメントリポジトリには問題ありませんが、簡単なREADMEには過剰です。
方法3:正確なレイアウトが必要な場合のカスタムスクリプト
既製のコンバーターでは、希望する形式を生成できない場合があります。タグごとに1つのMarkdownファイルが必要な場合、コンパクトなエンドポイントインデックスが必要な場合、または内部のスタイルガイドに合ったスキーマテーブルが必要な場合などです。その場合は、自分で仕様をパースし、出力をテンプレート化します。仕様は構造化されたデータに過ぎないので、思ったよりも作業は少なくて済みます。
すべての操作をリストアップする最小限のNodeバージョンは次のようになります。
import { readFileSync, writeFileSync } from "node:fs";
import yaml from "js-yaml";
const spec = yaml.load(readFileSync("openapi.yaml", "utf8"));
const lines = [`# ${spec.info.title}`, "", spec.info.description ?? "", ""];
for (const [path, methods] of Object.entries(spec.paths)) {
for (const [method, op] of Object.entries(methods)) {
lines.push(`## ${method.toUpperCase()} ${path}`);
lines.push("");
lines.push(op.summary ?? "");
lines.push("");
const params = op.parameters ?? [];
if (params.length) {
lines.push("| Name | In | Required | Description |");
lines.push("| ---- | -- | -------- | ----------- |");
for (const p of params) {
lines.push(`| ${p.name} | ${p.in} | ${p.required ? "yes" : "no"} | ${p.description ?? ""} |`);
}
lines.push("");
}
}
}
writeFileSync("api-reference.md", lines.join("\n"));
これは、出力に対する完全な制御を得るための約40行のコードです。見出し、テーブルの列、ファイルの分割は自分で決定します。欠点はメンテナンスです。対象とするOpenAPIバージョンに機能が追加された場合、スクリプトもそれを学ぶ必要があります。安定した内部スタイルであれば、このトレードオフは通常価値があります。広範な仕様をカバーするには、メンテナンスされているコンバーターに頼るべきです。これをスクリプトにするか、既成のツールを使うか悩んでいる場合は、Markdownエクスポート機能を備えたAPIドキュメントジェネレーターの比較で、メンテナンスされているオプションを比較検討できます。
方法4:仕様、ドキュメント、テストをApidogで一元管理する
上記のコンバーターはすべて、1つの盲点があります。それらは仕様をMarkdownに変換しますが、その後、両者は乖離してしまいます。誰かがAPIを編集し、コンバーターの再実行を忘れ、Markdownは嘘をつくことになります。この問題を解決するには、仕様を単独で存在するファイルとして扱うのをやめ、ドキュメントとテストがそれに合わせて更新されるワークスペースの一部として扱うことです。
それがApidogが採用しているモデルです。既存のopenapi.yamlをインポートすると、Apidogはすべてのパス、スキーマ、例をプロジェクトに読み込みます。そこから、インポートされた仕様から直接生成された、レンダリングされホストされたAPIドキュメントが得られます。個別のビルドステップは不要です。完全なインポートフローはSwaggerまたはOpenAPIをインポートしてリクエストを生成する方法で説明されており、仕様から公開されたリファレンスへのパスはOpenAPIからAPIドキュメントを自動生成するで説明されています。
これには、ワンショットコンバーターとは異なる2つの点があります。
第一に、ドキュメントは独自のMarkdownコンテンツブロックをサポートしています。生成されたエンドポイントリファレンスは仕様から得られ、その周りに手書きのMarkdown(入門ページ、認証に関する注意点、変更履歴エントリなど)を重ねることができます。Apidog Markdownでドキュメントを作成するためのヒントでは、そのオーサリング側を詳しく説明しています。したがって、生成されたドキュメントと手書きのドキュメントのどちらかを選ぶ必要はなく、両方を1か所で入手できます。
第二に、同じインポートされた仕様がテストシナリオの基礎となります。仕様で定義されたエンドポイントに対してリクエストとアサーションを構築し、それらを実行して、ライブAPIがドキュメントを作成した契約とまだ一致していることを証明します。これにより、乖離ループが閉じます。APIが変更されて契約が破られた場合、テストは失敗し、読者が知る前にドキュメントが古くなっていることがわかります。
手順に従うには、Apidogをダウンロードし、仕様をインポートして、同じプロジェクトで生成されたドキュメントを開きます。ポイントは、Apidogが.mdファイルをディスクに出力することではありません。それは、仕様、人間が読めるドキュメント、そして両方を正直に保つテストが、3つのばらばらのファイルでなくなることです。
自動化する:CIでMarkdownを再生成する
手動で実行するコンバーターは忘れられがちです。OpenAPIからMarkdownを生成する真の価値は、変更があるたびに自動的に生成が実行される場合にのみ発揮されます。パターンはシンプルです。仕様に触れるプッシュごとに、Markdownを再生成してコミットバックするか、公開します。
以下は、openapi.yamlが変更されるたびにリファレンスを再生成するGitHub Actionsジョブです。
name: Generate API docs
on:
push:
paths:
- "openapi.yaml"
jobs:
docs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: "20"
- name: Convert spec to Markdown
run: npx openapi-to-md openapi.yaml docs/api-reference.md
- name: Commit regenerated docs
run: |
git config user.name "docs-bot"
git config user.email "docs-bot@users.noreply.github.com"
git add docs/api-reference.md
git diff --staged --quiet || git commit -m "docs: regenerate API reference"
git push
これにより、Markdownが仕様から1コミット以上乖離することはありません。同じアイデアはGitLab CIやNodeまたはPythonが使えるあらゆるランナーで機能します。変換ステップをwiddershinsやあなたのスクリプトに置き換えるだけです。
もう一つ、組み込む価値のある要素があります。再生成されたドキュメントは、それが由来する仕様が正確である場合にのみ信頼できます。そこで、コマンドラインテストの実行が同じパイプラインでの位置を占めます。Apidog CLIは、インポートされた仕様に対して構築したテストシナリオを、ヘッドレスで、単一のコマンドで実行します。
npm install -g apidog-cli
apidog run --access-token $APIDOG_ACCESS_TOKEN -t 605067 -e 1629989 -r cli
いずれかのアサーションが失敗するとゼロ以外のコードで終了し、ビルドが失敗するため、もはやそのように動作しないAPIを記述するドキュメントの公開を防ぎます。完全なフラグ表面はapidog runコマンドリファレンスに、より広範なパイプライン設定はApidog CLI完全ガイドに記載されています。ドキュメント生成と契約テストを組み合わせることで、両者が相互に強化されます。仕様がドキュメントを生成し、テストが仕様を証明します。
生成されたMarkdownのクリーンアップ
生成されたMarkdownは、最初のパスでは完璧であることは稀です。いくつかの習慣で読みやすさを保つことができます。
- ターゲットレンダラーが必要としない場合、自動生成されたフロントマターを削除します。Widdershinsは
--omitHeaderで行いますが、他のツールではファイルの先頭に簡単なsedを適用することで機能します。 - ファイル分割を決定します。1つの巨大なMarkdownファイルはREADMEには問題ありません。ドキュメントサイトの場合は、各ページが短くなるようにタグまたはリソースで分割します。
- 例を現実的なものに保ちます。ほとんどのコンバーターは、例の値を仕様から直接取得するため、生成されたドキュメントの品質は、OpenAPIの
examplesの品質に依存します。より良い入力例から、より良い出力ドキュメントが得られます。 - 手作業で編集せず、再生成します。手作業で生成されたMarkdownを編集した途端、次の変換で上書きされてしまいます。手書きのコンテンツは別のファイルに置き、ジェネレーターには参照セクションのみを所有させます。
仕様自体が乱雑な場合は、ソースで修正してください。よりクリーンな仕様はよりクリーンなドキュメントを作成し、OpenAPIバリデーターツールの投稿では、醜い出力を生み出すギャップをリンティングする方法を示しています。
チームに合った方法を選ぶ
Markdownをどこに配置する必要があるか、どれだけの制御が必要かに応じてツールを選択してください。
- 1つのコマンドでリポジトリリファレンスが欲しいが、レイアウトにこだわりがない場合:
openapi-to-mdまたはopenapi-markdownを使用します。 - コードサンプル付きのドキュメントサイトを構築しており、テーマ可能なテンプレートが欲しい場合:Widdershinsを使用します。
- コンバーターでは対応できない独自の内部スタイルガイドがある場合:パース済み仕様に対して小さなスクリプトを作成します。
- ドキュメント、仕様、そしてそれらを正確に保つテストを1つのワークスペースで、ホストされた出力と別々のビルドプロセスなしで管理したい場合:Apidogに仕様をインポートします。
これらは相互に排他的なものではありません。多くのチームはApidogを仕様とホストされたドキュメントの真の情報源として使用し、その後CIでコンバーターを実行して、オフラインで読めるようにMarkdownリファレンスをリポジトリに配置しています。仕様は正規のままであり、Markdownはいつでも再生成できる派生成果物です。
まとめ
OpenAPIからMarkdownへの変換は、仕様をソースとし、Markdownを派生ファイルとして扱う限り、解決済みの問題です。高速なリポジトリリファレンスには、openapi-to-mdのようなワンラインコンバーターが役立ちます。テーマ設定可能なドキュメントサイトには、Widdershinsがテンプレートとコードタブを提供します。正確な内部レイアウトには、パース済み仕様に対する短いスクリプトが効果的です。そして、仕様、レンダリングされたドキュメント、およびそれらを同期させるテストを一緒に管理したい場合は、Apidogへのインポートにより、他のすべてのアプローチが時間とともに崩壊させる乖離が解消されます。
何を選ぶにしても、自動化してください。仕様が変更されるたびにCIでMarkdownを生成すれば、チームが読むドキュメントは常に、それが記述するAPIと一致するでしょう。
