extract-openapi-from-code について
既存の API プロジェクトから OpenAPI 仕様を抽出するスキルです。Python、Java、TypeScript、Ruby、PHP の 8 フレームワークに対応し、検証や SDK 生成まで案内します。
主な機能
- 018 つの API フレームワークに対応
- 02フレームワーク別の抽出方法
- 03OpenAPI の lint と検証
- 04Overlay による仕様の修正
- 05任意の SDK 生成
活用シーン
- 01既存 API の OpenAPI 文書化
- 02コードファースト API からの SDK 生成準備
- 03抽出した仕様の検証と修正
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ speakeasy-api/ sdk-generation-skills --skill extract-openapi-from-codeインストール後、Claude Code で/extract-openapi-from-codeを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
content/frameworks/django.mdfastapi.mdflask.mdhono.mdlaravel.mdnestjs.mdrails.mdspring-boot.md詳細
extract-openapi-from-code
既存の API コードベースから OpenAPI 仕様を抽出します。Python、Java、JavaScript/TypeScript、Ruby、PHP の主要な 8 つのフレームワークに対応しています。
コンテンツガイド
| フレームワーク | 言語 | ガイド |
|---|---|---|
| FastAPI | Python | content/frameworks/fastapi.md |
| Flask | Python | content/frameworks/flask.md |
| Django REST Framework | Python | content/frameworks/django.md |
| Spring Boot | Java | content/frameworks/spring-boot.md |
| NestJS | TypeScript | content/frameworks/nestjs.md |
| Hono | TypeScript | content/frameworks/hono.md |
| Rails | Ruby | content/frameworks/rails.md |
| Laravel | PHP | content/frameworks/laravel.md |
各ガイドでは、該当するフレームワークの詳細なセットアップ、スキーマ定義、Speakeasy 拡張、認証、トラブルシューティングについて説明しています。
使用する場面
- 既存の API があり、そこから OpenAPI 仕様を生成したい場合
- OpenAPI 仕様がまだないコードから SDK を作成したい場合
- 特定のフレームワーク(FastAPI、Flask、Django、Spring Boot、NestJS、Hono、Rails、Laravel)に言及している場合
- 「OpenAPI を抽出」「コードファースト」「コードから仕様を生成」「既存の API コード」といった要望がある場合
入力
| 入力 | 必須 | 説明 |
|---|---|---|
| フレームワーク | はい | 使用中の API フレームワーク(「判断フレームワーク」を参照) |
| プロジェクトパス | はい | API プロジェクトのルートディレクトリ |
| 出力パス | いいえ | 仕様を書き込む場所(デフォルト:openapi.json または openapi.yaml) |
| 対象言語 | いいえ | 抽出後に SDK を生成する場合の、SDK の対象言語 |
出力
| 出力 | 説明 |
|---|---|
| OpenAPI 仕様 | API を記述した JSON または YAML ファイル |
| 検証レポート | speakeasy lint による lint の結果 |
前提条件
- API プロジェクトをビルドでき、依存関係がインストールされている必要があります
- ランタイム抽出(FastAPI、Spring Boot、NestJS、Hono)では、アプリをインポートまたは起動できる必要があります
- 抽出後の検証と SDK 生成のために、
speakeasyCLI がインストールされている必要があります
判断フレームワーク
次のツリーを使って、抽出方法を判断してください。
| フレームワーク | 言語 | 方法 | サーバーの起動が必要ですか? |
|---|---|---|---|
| FastAPI | Python | 組み込みエクスポート | いいえ |
| Flask (flask-smorest) | Python | CLI コマンド | いいえ |
| Django REST Framework | Python | drf-spectacular CLI | いいえ |
| Spring Boot (springdoc) | Java | HTTP エンドポイント | はい |
| NestJS | TypeScript | HTTP エンドポイントまたはスクリプト | はい |
| Hono (zod-openapi) | TypeScript | プログラムからのエクスポート | いいえ |
| Rails (rswag) | Ruby | Rake タスク | いいえ |
| Laravel (l5-swagger) | PHP | Artisan コマンド | いいえ |
コマンド
以下から、使用するフレームワークに合ったコマンドを選んでください。抽出後は必ず speakeasy lint で検証してください。
Python:FastAPI
FastAPI は実行時に OpenAPI スキーマを生成します。サーバーを起動せずにエクスポートできます。
python -c "import json; from myapp import app; print(json.dumps(app.openapi()))" > openapi.json
myapp を、FastAPI の app インスタンスを含むモジュール名に置き換えてください。アプリがファクトリーパターンを使用している場合:
python -c "import json; from myapp import create_app; app = create_app(); print(json.dumps(app.openapi()))" > openapi.json
サーバーを起動して http://localhost:8000/openapi.json から取得することもできます。
Python:Flask (flask-smorest)
flask-smorest または apispec が必要です。
flask openapi write openapi.json
apispec を直接使用する場合は、プログラムからエクスポートします。
import json
from myapp import create_app, spec
app = create_app()
with app.app_context():
print(json.dumps(spec.to_dict()))
Python:Django REST Framework
drf-spectacular が必要です。
python manage.py spectacular --file openapi.yaml
JSON 形式で出力する場合:
python manage.py spectacular --format openapi-json --file openapi.json
Java:Spring Boot
springdoc-openapi が必要です。アプリケーションを起動し、仕様を取得します。
# Start the app (background)
./mvnw spring-boot:run &
# Wait for startup
sleep 15
# Fetch the spec
curl http://localhost:8080/v3/api-docs -o openapi.json
# For YAML format
curl http://localhost:8080/v3/api-docs.yaml -o openapi.yaml
# Stop the app
kill %1
サーバーが別のポートまたはコンテキストパスで実行されている場合は、それに応じて URL を調整してください。
TypeScript:NestJS
@nestjs/swagger が必要です。アプリケーションを起動してから、次のエンドポイントを取得します。
# Start the app (background)
npm run start &
sleep 10
# Fetch the spec (default path with SwaggerModule)
curl http://localhost:3000/api-json -o openapi.json
# Stop the app
kill %1
または、サーバーを起動せずにエクスポートするスクリプトを作成します。
// scripts/export-openapi.ts
import { NestFactory } from '@nestjs/core';
import { SwaggerModule, DocumentBuilder } from '@nestjs/swagger';
import { AppModule } from '../src/app.module';
import * as fs from 'fs';
async function bootstrap() {
const app = await NestFactory.create(AppModule, { logger: false });
const config = new DocumentBuilder().setTitle('API').build();
const doc = SwaggerModule.createDocument(app, config);
fs.writeFileSync('openapi.json', JSON.stringify(doc, null, 2));
await app.close();
}
bootstrap();
TypeScript:Hono(zod-openapi)
@hono/zod-openapi が必要です。プログラムからスキーマをエクスポートします。
// scripts/export-openapi.ts
import { app } from '../src/app';
import * as fs from 'fs';
const doc = app.doc('/doc', {
openapi: '3.1.0',
info: { title: 'API', version: '1.0.0' },
});
fs.writeFileSync('openapi.json', JSON.stringify(doc, null, 2));
次のコマンドで実行します。
npx tsx scripts/export-openapi.ts
Ruby:Rails(rswag)
rswag が必要です。
rails rswag:specs:swaggerize
デフォルトでは、仕様ファイルは swagger/v1/swagger.yaml に書き込まれます(config/initializers/rswag_api.rb で変更できます)。
PHP:Laravel(l5-swagger)
l5-swagger が必要です。
php artisan l5-swagger:generate
デフォルトでは、仕様ファイルは storage/api-docs/api-docs.json に書き込まれます。
抽出後の手順
仕様を抽出した後は、必ず次の手順を実行してください。
1. 仕様を検証する
speakeasy lint openapi --non-interactive -s openapi.json
2. オーバーレイで問題を修正する(必要な場合)
検証で問題が見つかった場合は、抽出した仕様を直接変更するのではなく、オーバーレイを使用してください。
speakeasy overlay apply -s openapi.json -o fixes.yaml
検証エラーを修正するには、OpenAPI オーバーレイファイルを作成し、speakeasy overlay apply -s <spec> -o <overlay> で適用します。
3. SDK を生成する
speakeasy quickstart --skip-interactive --output console \
-s openapi.json \
-t <target> \
-n <name> \
-p <package>
speakeasy quickstart -s <spec> -t <language> を実行して、新しい SDK プロジェクトを初期化します。
例
FastAPI プロジェクトのワークフロー全体:
# 1. Extract the OpenAPI spec
cd /path/to/my-fastapi-project
python -c "import json; from main import app; print(json.dumps(app.openapi()))" > openapi.json
# 2. Validate
speakeasy lint openapi --non-interactive -s openapi.json
# 3. Generate a TypeScript SDK
speakeasy quickstart --skip-interactive --output console \
-s openapi.json \
-t typescript \
-n "MyApiSDK" \
-p "my-api-sdk"
Speakeasy 拡張機能の追加
仕様を抽出した後、SDK の出力を改善するために Speakeasy 固有の拡張機能を追加します。フレームワークの設定、またはオーバーレイを使って追加できます。
FastAPI:openapi_extra で拡張機能を追加する
@app.get(
"/items",
openapi_extra={
"x-speakeasy-retries": {
"strategy": "backoff",
"backoff": {"initialInterval": 500, "maxInterval": 60000, "exponent": 1.5},
"statusCodes": ["5XX", "429"]
},
"x-speakeasy-group": "items",
"x-speakeasy-name-override": "list"
}
)
def list_items(): ...
Django:SPECTACULAR_SETTINGS で拡張機能を追加する
# settings.py
SPECTACULAR_SETTINGS = {
# ... other settings
'EXTENSIONS_TO_SCHEMA_FUNCTION': lambda generator, request, public: {
'x-speakeasy-retries': {
'strategy': 'backoff',
'backoff': {'initialInterval': 500, 'maxInterval': 60000, 'exponent': 1.5},
'statusCodes': ['5XX']
}
}
}
Spring Boot:カスタム OperationCustomizer で拡張機能を追加する
@Bean
public OperationCustomizer operationCustomizer() {
return (operation, handlerMethod) -> {
operation.addExtension("x-speakeasy-group",
handlerMethod.getBeanType().getSimpleName().replace("Controller", "").toLowerCase());
return operation;
};
}
NestJS:デコレーターオプションで拡張機能を追加する
@Get()
@ApiOperation({
summary: 'List items',
operationId: 'listItems'
})
@ApiExtension('x-speakeasy-group', 'items')
@ApiExtension('x-speakeasy-name-override', 'list')
listItems() { ... }
オーバーレイを使用する(任意のフレームワーク)
フレームワークのコードを変更できない場合は、オーバーレイを使用します。
overlay: 1.0.0
info:
title: Speakeasy Extensions
version: 1.0.0
actions:
- target: $.paths['/items'].get
update:
x-speakeasy-group: items
x-speakeasy-name-override: list
抽出後によくある問題
| 問題 | 症状 | 修正方法 |
|---|---|---|
| operationId がない | Lint 警告が表示される。SDK メソッド名が汎用的になる | オーバーレイで operationId を追加するか、speakeasy suggest operation-ids -s openapi.json を使用する |
| 説明がない | Lint のヒントが表示される。SDK にドキュメントがない | ソースコードまたはオーバーレイで、エンドポイントとスキーマに説明を追加する |
| スキーマの許容範囲が広すぎる | スキーマで additionalProperties: true が使われている、または型の制約がない | ソースコードでスキーマを厳格化する。より厳格な検証デコレーターを使用する |
| レスポンススキーマがない | Lint エラーが発生する。SDK の戻り値の型が any/object になる | フレームワークのエンドポイントに明示的なレスポンスモデルを追加する |
| operationId が重複している | Lint エラーが発生する。生成に失敗する | 各エンドポイントに一意の operationId が設定されていることを確認する |
| 認証がない | 仕様にセキュリティスキームがない | フレームワークの設定またはオーバーレイでセキュリティメタデータを追加する |
してはいけないこと
- OpenAPI 仕様を手書きしないでください。フレームワークで生成できる場合は、必ず先に抽出してください。
- 抽出した仕様を直接編集しないでください。修正にはオーバーレイを使用し、再抽出時に変更が失われないようにしてください。
- 検証を省略しないでください。抽出した仕様には、SDK の生成を妨げる問題が含まれていることがよくあります。
- 抽出した仕様が完全だと思い込まないでください。フレームワークによっては、認証、エラーレスポンス、ヘッダーが省略される場合があります。
- 抽出のために本番モードでサーバーを起動しないでください。開発用またはテスト用の設定を使用してください。
トラブルシューティング
| エラー | 原因 | 解決策 |
|---|---|---|
ModuleNotFoundError (Python) | アプリの依存関係がインストールされていません | pip install -r requirements.txt または pip install -e . を実行します |
| 接続が拒否されました (Spring Boot、NestJS) | サーバーが完全に起動していません | スリープ時間を延ばすか、準備完了までポーリングします |
| 空または最小限の仕様 | インポート時にルートが登録されていません | すべてのルートモジュールがインポートされていることを確認し、遅延読み込みを確認します |
| YAML の解析エラー | 抽出したファイルの構文が無効です | 再抽出し、print 文が標準出力に混入していないか確認します |
Cannot find module (Node.js) | 依存関係がインストールされていません | npm install または yarn install を実行します |
/v3/api-docs エンドポイントがありません (Spring Boot) | springdoc が設定されていません | 依存関係に springdoc-openapi-starter-webmvc-ui を追加します |
/api-json エンドポイントがありません (NestJS) | Swagger モジュールが設定されていません | main.ts で SwaggerModule.setup(app, ...) を設定します |
関連スキル
manage-openapi-overlays- オーバーレイで x-speakeasy-* 拡張を追加しますstart-new-sdk-project- 抽出後に SDK を生成します