目次


RESTful API の文書化と定義に Swagger を使用する

Swagger のプロパティーを拡張して REST API ドキュメントをカスタマイズして作成する

Comments

多くの 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 は、次のようになります。

使用中の Swagger エディターを示すスクリーンショット
使用中の Swagger エディターを示すスクリーンショット

上のスクリーンショットに重ねて示されている矢印は、プレビュー・ドキュメント内の 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 のレスポンスを文書化するには、OBJECTotherOBJECT を別の値に設定すればよいだけです。

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 文書を参照してください)。

lead_source に対してレンダリングされた HTML ページのスクリーンショット
lead_source に対してレンダリングされた HTML ページのスクリーンショット

以下に、leads API エンドポイントの HTTP POST メソッドに対して生成された HTML ページを示します (「サンプルを含める」セクションで対応するYAML 文書を参照してください)。

HTTP POST に対してレンダリングされた HTML ページのスクリーンショット
HTTP POST に対してレンダリングされた HTML ページのスクリーンショット

追記

この API-swagger.zip ファイル (「ダウンロード」を参照) でデモンストレーションしているのは、SalesConnect システムに含まれる OAuthLeadNote という 3 つのモジュールに関する Swagger API ドキュメントのサブセットです。これらの API は /modules ディレクトリー内にあり、対応するサンプルは /samples ディレクトリーに格納されています。

HTML ページを生成する手順は以下のとおりです。

  1. 前提条件ソフトウェア (PHP および PHP YAML 拡張) をインストールします。
  2. cd を使用してカレント・ディレクトリーを API-Swagger ディレクトリーに変更します。
  3. MASTER.yaml ファイルのデモ・パッケージ・セットに指定されているすべての API に関する HTML を生成する場合は、次のコマンドを入力します (1 行で入力してください)。php tools/swagger-to-html.php salesconnect.swagger/MASTER.yaml --set demo > c:/swagger/salesconnectAPI.html
  4. 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 として出力することも可能になります。


ダウンロード可能なリソース


関連トピック


コメント

コメントを登録するにはサインインあるいは登録してください。

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=60
Zone=Web development, Open source
ArticleID=1038552
ArticleTitle=RESTful API の文書化と定義に Swagger を使用する
publish-date=10202016