多くの Web アプリケーションが RESTful API をサポートしていますが、REST API は SOAP API とは異なり、HTTP メソッドに依存していて、コンシューマーとプロバイダーとの間のリクエストとレスポンスの構造体を定義する WSDL (Web Services Description Language) に相当する決まり事がありません。適切な契約サービスなしで、多くの REST API プロバイダーは Microsoft Word ドキュメントや Wiki ページを使って API の使用法を文書化しています。これらのフォーマットは、いくつもの API やリソースを持つアプリケーションにおいて、または API の反復的開発が進行中である場合に、コラボレーションにもドキュメントのバージョン管理にも違いを生じさせる可能性があります。また、このようなタイプのドキュメントだと、自動化されたテスト・アプリケーションに統合するのも難しくなります。
このような API のユーザーと開発者に不利な問題を解消するために役立つのが、オープンソース Swagger フレームワークです。このフレームワークは、JSON または YAML (人間が読んで理解しやすい、JSON のスーパーセット) でフォーマット化された RESTful API ドキュメントを作成するための OpenAPI 仕様 (旧称 Swagger 仕様) を規定しています。Swagger ドキュメントはさまざまなプログラミング言語で処理することができ、ソフトウェア開発サイクル中にバージョン管理を行うために、ソース管理にチェックインすることができます。
ただし、Swgger には固有の短所もあります。私たちが Swagger フレームワークを使って独自の API を文書化したときに、ドキュメントのニーズと Swagger の基本機能の間にはギャップがあることがわかりました。この記事では、私たちが文書化プロセスで直面した課題を取り上げ、これらの課題に対処するために取った以下のソリューションを紹介します。
- Swagger 拡張機能の実装
- Swagger のドキュメント集約機能の簡素化
- Swagger ドキュメントを HTML ページに出力するためのツールの作成
私たちが開発したこれらのソリューションはダウンロード可能です。ダウンロードしたサンプル・コードは、Swagger で文書化する皆さん独自の RESTful API にも適応できます。この記事で説明する手法に従って、独自のカスタマイズを Swagger に加えてください。
Swagger を使用する
Swagger のさまざまな編集ツールを利用すると、API ドキュメントを簡単に作成したり、作成したドキュメントが OpenAPI 仕様に準拠していることを確認したりできます。例えば、 Swagger エディター では、API ドキュメントを作成またはインポートして、そのドキュメントをインタラクティブな環境でブラウズすることができます。右側の表示ペインには、フォーマット化されたドキュメントが表示され、左側のコード・エディターで行われた変更が反映されます。コード・エディターは、フォーマットに誤りがあればそれを指摘します。また、これらのペインのいずれかを展開/縮小することもできます。
leads.yaml 定義をインポートした後の Swagger エディター UI は、次のようになります。
上のスクリーンショットに重ねて示されている矢印は、プレビュー・ドキュメント内の POST
API と GET
API のそれぞれに対応する、OpenAPI 仕様に準拠した leads.yaml ファイル内での post:
定義と get:
定義を指しています。
Eclipse を IDE として使用している場合は、 YEdit を利用できます。YEdit は、YAML 構文をチェックおよび強調表示し、編集機能とフォーマット化機能を提供するツールです。
Swagger を拡張する
Swagger の既存のツールによって、API ドキュメントを簡単に編集できるようになってはいますが、文書化のシナリオによっては問題が生じることもあります。Swagger を使って API を文書化する際に、私たちはいくつかの現実的な問題に直面しました。
- API のユーザーには、私たちが開発した API に固有の情報が必要だったものの、そのための標準がOpenAPI 仕様に組み込まれていなかった。
- API のユーザーはリクエストとレスポンスのサンプルを必要としていたが、既存のエディターにはそれらのサンプルが用意されていなかった。
- API ユーザー用のサンプルを (理想としてはオンライン HTML ドキュメントで) 含む、リッチで人間が読んで理解できるドキュメントを用意しなければならなかった。
以上の問題に対処するために、私たちは OpenAPI 仕様をベースに独自の属性、ツール、テンプレートを作成しました。
プロパティーを拡張する
Swagger は、 x-
拡張プロパティーを使用して拡張できるようになっています。ここでは、私たちの API に合わせてカスタマイズした拡張機能と、それぞれの使用例を紹介します。
以下のプロパティーは、API ペイロードまたはレスポンスのフィールドに関するものです。
x-sc-crud
: API フィールドの有効な作成、読み取り、更新、および削除 (CRUD) 操作を文書化します。x-sc-crud: [ read, update, create ]
x-sc-required
: 当該フィールドで必要な CRUD 操作を示します。x-sc-required: [ create ]
x-sc-fieldmap
: データベース表と、指定の API フィールドに関連付けられている UI フィールドを文書化します。x-sc-fieldmap: table: TASKS_RELATED_TO uifieldname: Related to
x-sc-enum
: API フィールドに有効な値を文書化します。静的な値のリストではなく、現在の有効な値一式を返す API を指定することができます。x-sc-enum: api: /leads/enum/alt_address_country
x-sc-comments
:description
プロパティーを補完し、特定の API フィールドに関する一時的な追加情報を取り込むために使用されます。x-sc-comments: - readonly in UI, aka Domestic Buying Group or DB
以下のコード・リスティングは、 Lead
モジュールに含まれる lead_source
API フィールドの x-sc
プロパティーを YAML で定義した場合の例です。
lead_source:
type: string
maxLength: 100
externalDocs:
description: Lead Source // Current (0100) // Approved // op - Opportunity
url: https://w3.ibm.com/standards/information/tmt/output/Approved/
ibmww/op/bds/Opportunity_Management/Lead_Source.html
#
# lead_source value is returned when retrieving a lead,
# and you can set its value when creating or updating a Lead.
#
x-sc-crud: [ read, update, create ]
#
# The lead_source is a required field when creating a Lead.
#
x-sc-required: [ create ]
#
# You can retrieve valid lead_source values from the
# /leads/enum/lead_source API.
#
x-sc-enum:
api: /leads/enum/lead_source
AVL:
dictionary_name: leads_lead_source_dom
example: LinkedIn
#
# The value of lead_source is saved in the LEADS table.
# In UI, you can find lead_source under the "Lead Source" label.
#
x-sc-fieldmap:
table: LEADS
uifieldname: Lead Source
以下のプロパティーは、API 操作の説明を拡張します。
x-sc-samples
: サンプルを文書化します。このプロパティーは、ドキュメントのサンプル・セクションへの JSON 参照のリストで構成されます(詳細については、「 サンプルを含める 」を参照)。x-sc-samples: - $ref: '#/x-sc-samples/leads-post-create-lead' - $ref: '#/x-sc-samples/leads-post-create-lead-employeecnum'
x-sc-APIm-plans
: 当該操作が属する IBM API Connect (旧称 IBM API Management) プランを一覧表示します。API Manager に固有の情報を取り込む必要があるためです。x-sc-APIm-plans: - salesconnect_leads_read
以下のコード・リスティングは、 /leads
API エンドポイントの HTTP POST
メソッド用 YAML リソースに含まれる x-sc
プロパティーの例です。
paths:
/leads:
parameters:
- $ref: 'MASTER#/parameters/OAuthToken'
- $ref: 'MASTER#/parameters/ContentType'
post:
summary: create lead
tags: [ leads ]
#
# Use the x-sc-APIm-plans property to specify that this endpoint
# is in APIm's salesconnect_leads_create plan.
#
x-sc-APIm-plans:
- salesconnect_leads_create
description: |
<p>API to create a lead.</p>
#
# Use the x-sc-samples property to refer to samples of the usage
# of the /leads API.
#
x-sc-samples:
- $ref: '#/x-sc-samples/leads-post-create-lead'
- $ref: '#/x-sc-samples/leads-post-create-lead-employeecnum'
parameters:
- name: lead_definition
in: body
description: definition of lead to be created
schema:
$ref: '#/definitions/LeadObject'
responses:
200:
$ref: '#/responses/LeadObjectResponse'
422:
description: |
<p>scenarios</p>
<ul>
<li>missing required field</li>
<li>invalid values for optional fields</li>
<li>et cetera</li>
</ul>
サンプルを含める
Swagger は RESTful API を定義するための強力なツールではあるものの、HTTP リクエストおよびレスポンスのサンプルを含める方法や、開発者用に作成されたドキュメントを追加する方法はまだ提供していません。
リクエストとレスポンスのサンプルを含めるため、私たちは仕様を拡張し、この場合も YAML を使用してサンプルを文書化しました。メインの API ドキュメントを必要以上に複雑にしないために、サンプルは別個のスキーマに分離することにしました。
以下に示す leads-post-create-lead
のサンプルでは、URL、メソッド、ヘッダー、URL パラメーター、入力 (サンプル・ペイロード)、およびレスポンスを記述して、ユーザーに /leads
API の HTTP POST
メソッドを呼び出す方法を説明しています。
x-sc-samples:
leads-post-create-lead:
title: Create a New lead
description: |
This sample creates a new lead, and assigns it to a user specified via sugar user id.
method: POST
url: https://w3-dev.api.ibm.com/sales/development/salesconnect/leads
headers: |
Content-Type: application/json
Oauth-Token: 111e567a-7624-35f7-ed82-540f5a954312
Parameters: ?client_id={client_id}&client_secret={client_secret}
Input: |
{
"created_by": "eve25@tst.ibm.com",
"assigned_user_id": "51449f9b-a68f-059c-ad06-5039325c53b2",
"description": "2015-01-27 leads test",
"first_name": "one",
"last_name": "smith",
"phone_mobile": "22-222-2222",
...
}
Response: |
{
"my_favorite": false,
"following": false,
"id": "a260acfb-5b3e-3f74-2392-54d92387fb80",
"name": "one smith"
...
"_module": "Leads"
}
/leads
API セクションの HTTP POST
メソッド内では、拡張プロパティー x-sc-samples
で、 x-sc-samples
スキーマ内のサンプル・コード leads-post-create-lead
への JSON 参照を指定しています。
paths:
/leads:
parameters:
- $ref: 'MASTER#/parameters/OAuthToken'
- $ref: 'MASTER#/parameters/ContentType'
post:
summary: create lead
tags: [ leads ]
x-sc-APIm-plans:
- salesconnect_leads_create
description: |
<p>API to create a lead.</p>
#
# Use the x-sc-samples property to refer to samples of the usage
# of the /leads API.
#
x-sc-samples:
- $ref: '#/x-sc-samples/leads-post-create-lead'
- $ref: '#/x-sc-samples/leads-post-create-lead-employeecnum'
parameters:
- name: lead_definition
in: body
description: definition of lead to be created
schema:
$ref: '#/definitions/LeadObject'
responses:
200:
$ref: '#/responses/LeadObjectResponse'
422:
description: |
<p>scenarios</li>
<ul>
<li>missing required field</li>
<li> invalid values for optional fields</li>
<li> et cetera</li>
</ul>
定義とサンプルを結び付ける
モジュール定義とサンプルを結び付けるために、私たちは MASTER.yaml ファイルを使用しました。このファイルは、ロジスティック情報 (Swagger バージョン、API バージョン、全体的な情報、API が動作する相対基本パスなど) を文書化しています。
swagger: '2.0'
info:
version: '3.4'
title: Sales Connect API
#
#
description: >
This is the SalesConnect API.
<p> There are several modules, each with different top level path.
Most of the modules follow the same general pattern for operations and results,
varying in the Sales Connect object that is manipulated.</p>
<p> The individual module descriptions show
the particular operations and any module specific details.</p>
#
#
basePath: /sales/test/salesconnect
host: w3-dev.api.ibm.com
さらに、MASTER.yaml にはパッケージ、共有オブジェクト、およびテンプレートに関する注釈も入っています。
パッケージ
MASTER.yaml ファイルに package
および package sets
プロパティーを定義すると、コンテンツを動的に生成できるようになります。パッケージとは、特定のモジュールに関連するすべての YAML ファイルを定義するものです。一方、パッケージ・セットとは、最終的なドキュメントの内容を細かく制御するパッケージの集合を指します。以下の例では、 demo
および default
パッケージ・セットのそれぞれが、異なるファイル一式から内容をプルします。パッケージとパッケージ・セットの組み合わせを使用することで、リリース済みモジュールと開発中のモジュールとを簡単に切り分けることができます。
x-sc-master:
packages:
bulk:
- modules/bulk
#
# The oauth package contains 2 files:
# - the modules/oauth.yaml file
# - the samples/oauth-samples.yaml file
#
oauth:
- modules/oauth
- samples/oauth-samples
calls:
- modules/calls
- samples/calls-samples
collab:
- modules/collab
notes:
- modules/notes
- samples/notes-samples
...
leads:
- modules/leads
- samples/leads-samples
- samples/leadsTBD-samples
...
package-sets:
#
# When generating a "default" document, our tool pulls
# content from files specified under the "oauth", "bulk",
# "calls", "collab" and "notes" packages.
#
default:
- oauth
- bulk
- calls
- collab
- notes
#
# When generating a "demo" document, our tool pulls
# in a different set of files.
#
demo:
- oauth
- notes
- leads
共有オブジェクト
実装プロセス中に、私たちは一部のオブジェクトが繰り返し言及されていることに気付きました。多数の API バックエンドで同じフィルター URL パラメーターが使用されていること、多数の API の GET
メソッドが同じ基本フィールド一式を返すこと、そして API Manager がさまざまな呼び出しに対して同じエラー・メッセージ・フォーマットを返すことが、その原因でした。そこで、冗長性を軽減するために、 BasicObject
プロパティーと APImException オブジェクトを使用して、これらの重複する要素を MASTER.yaml ファイルに抽出することにしました。BasicObject プロパティーで HTTP メソッドのすべての GET
API から返す基本フィールドを定義し、 APImException
オブジェクトで API Manager から返すエラー構造体を記述するという方法です。
テンプレートを使用する
多くの API のレスポンスは同じようなパターンに従うことから、重複を減らすとともにバリエーションに対応する各種のテンプレートを設計することにしました。例えば、モジュールが別のモジュールにリンクされている場合、API によっては、そのレスポンスに両方のモジュールからのオブジェクトを格納します。この状況に対応するために、MASTER.yaml ファイル内に以下の (OBJECT)Link(otherOBJECT)Response
テンプレートを作成しました。
(OBJECT)Link(otherOBJECT)Response:
description: |
Result of creating link from (OBJECT) to (otherOBJECT).
The record contains the (OBJECT) and the related_record the (otherOBJECT) objects.
schema:
properties:
record:
$ref: 'MASTER#/definitions/(OBJECT)'
related_record:
$ref: 'MASTER#/definitions/(otherOBJECT)'
Node
モジュール (OBJECT=NoteObject)
を Account
モジュール (otherOBJECT=AccountObject)
にリンクする API のレスポンスを文書化する場合は、以下のフォーマットを使用できます。
post:
summary: Establish an accounts link to note using ccms id.
description: Establish an accounts link to note using ccms id.
responses:
default:
$ref: 'MASTER?OBJECT=NoteObject&otherOBJECT=AccountObject#/responses/
(OBJECT)Link(otherOBJECT)Response'
この例では、 $ref
がツールに対して、MASTER.yaml ファイルにアクセスし、レスポンス・スキーマ内の (OBJECT)Link(otherOBJECT)Response
オブジェクトを調べるように指示します。JSON 参照をインスタンス化する前に、ツールは OBJECT
変数を NoteObject
で置き換え、 otherOBJECT
変数を AccountObject
で置き換えます。最終的には、テンプレートが以下のように展開されます。
NoteObjectLinkAccountObjectResponse:
description: |
Result of creating link from NoteObject to AccountObject.
The record contains the NoteObject and the related_record the AccountObject objects.
schema:
properties:
record:
$ref: 'MASTER#/definitions/NoteObject'
related_record:
$ref: 'MASTER#/definitions/AccountObject'
同様に、このテンプレートを使用して Note
モジュールを Opportunity
モジュールにリンクする API のレスポンスを文書化するには、 OBJECT
と otherOBJECT
を別の値に設定すればよいだけです。
post:
summary: Link from note to opportunity.
description: Link from note to opportunity.
x-sc-APIm-plans: [ salesconnect_notes_create ]
responses:
default:
$ref:
'MASTER?OBJECT=NoteObject&otherOBJECT=OpportunityObject#/responses/
(OBJECT)Link(otherOBJECT)Response'
YAML ドキュメントを HTML ページに変換する
API ドキュメントをよりユーザー・フレンドリーにするために、YAML ドキュメントを静的 HTML に変換するツール (swagger-to-html.php) を実装しました。Swagger から HTML ドキュメントを作成するためのツールは既にありましたが、 x-sc-*
拡張機能専用のハンドラーを追加できるよう、独自のツールを作成することにしたのです。
このツールは、MASTER.yaml ファイルを読み取り、必要なすべての YAML ファイルをマージし、参照を解決し、そして最終的に HTMLページを出力します。ツールが受け入れる各種パラメーターを利用することで、HTML ファイルの内容をカスタマイズすることもできます。例えば、特定のモジュールや特定のパッケージ・セットの HTML ファイルを生成したり、IBM API Management アプリケーションに登録されている API だけを対象とした HTML ファイルを生成したりできます。
生成される HTML は単一のファイルです。このファイルでは、CSS を使用してスタイルが設定され、JavaScript を使用してセクションの展開/縮小およびナビゲーション機能を自動化します。HTML ジェネレーター・ツールは、一般的な JSON オブジェクト、JSON スキーマ定義、そしてパラメーター、レスポンス、操作などに関する Swagger 記述をレンダリングします。
以下に、 Lead
モジュールに含まれる lead_source
項目に対して生成された HTML ページを示します (「 プロパティーを拡張する 」セクションで対応するYAML 文書を参照してください)。
以下に、 leads
API エンドポイントの HTTP POST
メソッドに対して生成された HTML ページを示します (「 サンプルを含める 」セクションで対応するYAML 文書を参照してください)。
追記
この API-swagger.zip ファイルでデモンストレーションしているのは、 SalesConnect
システムに含まれる OAuth
、 Lead
、 Note
という 3 つのモジュールに関する Swagger API ドキュメントのサブセットです。これらの API は /modules ディレクトリー内にあり、対応するサンプルは /samples ディレクトリーに格納されています。
HTML ページを生成する手順は以下のとおりです。
- 前提条件ソフトウェア (PHP および PHP YAML 拡張) をインストールします。
cd
を使用してカレント・ディレクトリーを API-Swagger ディレクトリーに変更します。- MASTER.yaml ファイルのデモ・パッケージ・セットに指定されているすべての API に関する HTML を生成する場合は、次のコマンドを入力します (1 行で入力してください)。
php tools/swagger-to-html.php salesconnect.swagger/MASTER.yaml --set demo > c:/swagger/salesconnectAPI.html
OAuth
およびLead
に関する HTML を生成する場合は、次のコマンドを入力します (1 行で入力してください)。php tools/swagger-to-html.php salesconnect.swagger/MASTER.yaml --modules oauth,leads > c:/swagger/salesconnectAPI.html
まとめ
Swagger は、RESTful API の文書化に威力を発揮するツールです。このツールにカスタム拡張機能、ツール、テンプレートを実装すれば、さらに多くの選択肢が加わり、Swagger で生成されるドキュメントのフォーマットと内容をさらに柔軟に制御できるようになります。Swagger の機能を拡張することで、API ドキュメントに API 固有の詳細を追加したり、HTTP リクエストおよびレスポンスを指定したりできるだけでなく、開発者と API ユーザーの両方が読めるよう、ドキュメントを HTML として出力することも可能になります。