みなさんこんにちはエンジニアのEadaedaです。
皆さんのチームではAPIドキュメントの生成に何をお使いですか?UniqysチームではReDocを使っています。 nestjs/swaggerを使ってコントローラーから生成したOpenAPIの定義ファイルを与えるだけでリッチなドキュメントを作ってくれるのでいい感じです。
プロダクトの開発をすすめるうちに、Webhookに関するドキュメントも必要になりました。しかし、nestjs/swagger
(2022/05/25時点のlatestである v5.2.1)では、Webhookのドキュメント生成に標準対応していませんでした。この記事ではこの問題に対処する方法の一つを紹介したいと思います。
前置き
OpenAPI 3.1で webhooks
フィールドを用いてWebhookのドキュメントを生成する
OpenAPI 3.1からは webhooks
というフィールドが追加になったので、これを使ってReDocにドキュメントを生成させることができます。例えば以下のような定義ファイルだとして
{ "openapi": "3.1.0", "info": { "title": "とてもすごいAPI", "description": "すごいAPIのドキュメントだよ", "version": "1.0" }, "components": { "schemas": { "Model": { "type": "object", "properties": { "name": { "type": "string", "example": "API太郎", "description": "あなたの名前だよ" }, "age": { "type": "number", "example": "3000", "description": "あなたの年齢だよ" } } } } }, "webhooks": { "sugoi-webhook": { "post": { "summary": "すごいWebhook", "operationId": "sugoi-webhook", "tags": ["Webhook"], "description": "すごいWebhookを送信するよ", "requestBody": { "description": "Webhookにより送信されるデータだよ", "content": { "application/json; charset=utf-8": { "schema": { "$ref": "#/components/schemas/Model" } } } }, "responses": { "200": { "description": "" } } } } } }
以下のようなドキュメントが生成されます。
とてもいい感じですね。これを使ってドキュメント更に充実させていきたいところですが、先にも述べたように、nestjs/swagger
では webhooks
を含むような定義ファイルを生成できません。さらに言うとOpenAPI 3.0な定義ファイルを生成するので、webhooks
フィールドも使えませんでした。
OpenAPI 3.0 で x-webhooks
フィールドを用いて、Webhookのドキュメントを生成する
なにか解決策は無いかと色々探していたところ、ReDocのドキュメントに x-webhooks
というものを発見しました。
x-webhooks
フィールドをOpenAPIのルートに記述することで、OpenAPI 3.1のwebhooks
で生成されるドキュメントをOpenAPI 2.0/3.0でも生成できるようです。試してみましょう。
{ "openapi": "3.0.0", "info": { ... }, "components": { ... }, "x-webhooks": { "sugoi-webhook": { "post": { "summary": "すごいWebhook", "operationId": "sugoi-webhook", "tags": ["Webhook"], "description": "すごいWebhookを送信するよ。OpenAPI 3.0だけど`x-webhooks`を使って書いているよ", "requestBody": { "description": "Webhookにより送信されるデータだよ", "content": { "application/json; charset=utf-8": { "schema": { "$ref": "#/components/schemas/Model" } } } }, "responses": { "200": { "description": "" } } } } } }
良さそうですね。
本題
swaggerの定義ファイル生成時に x-webhooks
を差し込み、Webhookのドキュメントを生成する
OpenAPI 3.0な定義ファイルを生成するnestjs/swagger
では、x-webhooks
を使えば良いことはわかりました。ただ、定義ファイル生成のたびに手で追記するのは大変なのでどうにか自動で行いたいです。いくつか方法はあると思うのですが、ここではTypeScriptで生成したドキュメントオブジェクトに直接挿入する方法で行いたいと思います。
import { SwaggerModule, DocumentBuilder } from "@nestjs/swagger"; import { INestApplication } from "@nestjs/common"; export function build(app: INestApplication) { const options = new DocumentBuilder() .setTitle("とてもすごいAPI") .setVersion("1.0") .setDescription("すごいAPIのドキュメントだよ"); const document = SwaggerModule.createDocument(app, options); (document as any)["x-webhooks"] = { "sugoi-webhook": { post: { summary: "すごいWebhook", operationId: "sugoi-webhook", tags: ["Webhook"], description: "すごいWebhookを送信するよ。OpenAPI 3.0だけど`x-webhooks`を使って書いているよ", requestBody: { description: "Webhookにより送信されるデータだよ", content: { "application/json; charset=utf-8": { schema: { $ref: "#/components/schemas/Model" } } } }, responses: { 200: { description: "", }, }, }, }, }; return document; }
特に工夫もないですが…。後はこの関数が返してきたオブジェクトをファイルに書き出すだけですね。
まとめ
- OpenAPI 3.1からは
webhooks
フィールドを定義すると、ReDocでWebhookのドキュメントが生成されるようになる - OpenAPI 3.0では
x-webhooks
フィールドを代わりに定義することで、同様にReDocでWebhookのドキュメントが生成されるようになる - しかし、
nestjs/swagger
(v5.2.1)では、webhooks
とx-webhooks
に標準対応していない - そこで、
x-webhooks
を直接差し込むコードを記述し、定義ファイルの生成時に実行することで自動生成をするようにした
ちなみに、この対応は以下のIssueが解決するまでの対応となります。
以上です。