複数の API のドキュメントポータルを構築する

パート1 - 初期レイアウトとデザイン
  2018年11月12日

Swagger UISlateSpectacleのようなプロジェクトは優れたドキュメント機能を提供しますが、単一のAPIの提示に重点を置いています。しかし、単一のポータルを通じて複数のAPIのドキュメントをきれいに提供したい場合はどうすればよいでしょうか?

公開APIをサポートするチームの数が増えたり、他のチームに「内部カタログ」を提供する必要があるグループが増えたりする中で、ユーザーがさまざまなAPIがどのように連携するかを理解するための1つの場所を持つことは非常に重要です。適切に設計され、維持されたドキュメントは、採用を増やし、サービスを使用する上でのベストプラクティスを強制するのに役立ち、新しい機能がオンラインになったときに提示するのに最適な方法です。

このシリーズでは、React.jsを使用してOAS定義をSwagger UIに動的に渡し(パート1)、この基本的なポータルをカスタマイズし(パート2)、最後に外部ホストにデプロイする(パート3)ことで、ソリューションを作成します。このシリーズのさらなるパートでは、「ウォークスルー」スタイルのページでドキュメントを強化したり、プライベートにホストされた定義に接続したりするなど、より小さな機能に焦点を当てます。SwaggerHubはAPI仕様のホストとして機能しますが、シリーズの後半ではそれらをロードするための代替オプションを探ります。

この手順は、ReactとOpenAPIに多少慣れている方を対象としていますが、ツールに初めて触れる方でも簡単に従えるはずです。

最終ポータルのテンプレートバージョンはこちらで、このプロジェクトを開始するために利用できます。実行中の例はこちらでホストされています。

OpenAPI、Swagger UI、またはSwaggerHubとは何ですか?

OpenAPI Specification (OAS) は、Linux Foundationの一部であるOpenAPI Initiativeによって維持されているREST定義標準です。この仕様は最近バージョン3.0がリリースされ、業界全体での採用とサポートが拡大し続けています。OASのような標準は、「デザインファースト」または「定義駆動型」開発戦略を促進し、関係者がコードに着手する前にAPIとその機能を計画することを可能にします。計画が全員で共有されるため、今後の変更やテスト要件をより早く伝えることができます。

Swagger UI は、OASの作業をサポートするオープンソースプロジェクトのコレクションであるSwaggerツールセットに含まれています。これは、最小限の設定でインタラクティブなドキュメントを迅速に提供する方法として、定義と並行して長年使用されてきました。このシングルページアプリケーションでは、Swagger UIによって提供されるnodeパッケージを活用します。

SwaggerHub は、SmartBearがゼロから構築したプラットフォームソリューションで、OASを大規模にサポートします。これは、単一の組織またはチームによって管理される複数の異なるAPIを持つという考え方とうまく連携し、そのバックエンドを使用して、必要に応じてドキュメントポータルにAPIをロードできます。SwaggerHubのようなツールを使用することで、APIコンシューマに表示される「現在の」仕様を更新および定義しながら、継続的な設計と開発もサポートできます。


環境設定

使用するツールを理解したので、プロジェクトを構築するために必要な依存関係があることを確認しましょう。シリーズの後半では、これを外部ホストにデプロイしたり、コンテナ内で実行したりする方法について説明しますが、ここではまずローカルで実行できるようにします。ここでの目標は、デプロイオプションを開いたままにするために、できるだけ少ない構成で行うことです。したがって、最初は単一の要件のみがあります:NodeJS

初期の出発点を構築するためにnpxを使用するため、node -vを実行して、5.2.0より新しいnodeバージョンがインストールされていることを確認してください。

React開発環境全体を構築する代わりに、create-react-appプロジェクトを出発点として使用します。これにより、すべての依存関係と基本構造が単一のコマンドで提供されます。

開始するには、プロジェクトを格納する親フォルダに移動し、npx create-react-app oas-doc-portalを実行します。

NPXが基本プロジェクトの構築を行います。新しいプロジェクトフォルダに移動してデフォルトアプリを起動することで、すべてがスムーズに進んだことを確認できます。

$ cd oas-doc-portal
$ npm start

react_default.JPG

ブラウザですべてが正しくレンダリングされれば、これを定義リポジトリに接続する作業に進むことができます。

これは、プロジェクトを選択したGITリポジトリシステムに接続し、最初のプッシュを行う良い機会でもあります。

単一の仕様をレンダリングする

定義を動的に渡すような冒険的なことをする前に、リモートリソースから単一の定義をロードしてレンダリングできることを確認しましょう。これにより、作業の確かな出発点が得られ、何かを必然的に壊したときに簡単に認識できます。このチュートリアルでは、Swagger Petstoreの定義を使用します。これは次の場所で入手できます。Swagger Petstore: https://petstore.swagger.io/v2/swagger.json

すべての魔法はswagger-ui nodeパッケージを通じて行われるので、ctrl+cを使用してアプリケーションを停止し、アプリケーションに追加しましょう。

  • npm install swagger-uiを実行して、プロジェクトにswagger-uiをインストールします。
  • /src/App.jsを開きます。
  • ページ上部のインポートステートメントの下にswagger-uiを追加します。

後で再構成する手間を省くために、コンストラクタをアプリに追加し、OASリンクの状態を作成できます。この値は新しいOASリンクで随時更新されるため、参照を保持するのに最適な場所です。この記事は、Reactが状態をどのように処理するかについてもう少し詳しく説明しています。

swagger-uiに定義リンクを渡すことで、ドキュメントをレンダリングします。リンクはすぐに動的に更新されるため、すべてを最新の状態に保つためにReactのライフサイクルを利用する必要があります。この場合、componentDidMountがその役割を果たします(要件の変更に伴い、後で調整します)。

  • 以前に定義したコンストラクタの下に、以下を追加します。

Swagger UIコンポーネントは、レンダリング方法に応じてさまざまなパラメータをサポートしていますが、初期のユースケースでは以下の通りです。

  • 次に作成するapi-data要素内にドキュメントをレンダリングするように指示しています。
  • 状態オブジェクトに保存されたURLへの参照で、定義をどこからロードするかを指示します。

create-react-appによって生成されたプレースホルダーレンダリング要素を削除し、新しく定義したdiv要件に置き換えます。

これでSwagger UIはページ上のapi-data要素を探し、その中にドキュメントをレンダリングします。アプリケーションを開始し、ブラウザを再読み込みすると、以前のプレースホルダーページにSwagger Petstoreの基本的な表現が表示されるはずです!

react_basic-(1).JPG

見た目は良くありませんが、データはそこにあります。そして、definitionLinkの値を手動で更新して、新しいAPIデータをレンダリングできるようになりました。本質的に、次のステップでは、これをアプリケーション自体の一部として行うことを目指します。

現時点でのアプリは次のようになります。


定義を動的に更新する

私たちのポータルの最終目標は、APIのリストを表示し、それぞれのAPIをクリックして、メインウィンドウでドキュメントの更新を確認することです。これを行うには、サイドバーにリストを表示し、ユーザーがリストを順にクリックするたびにdefinitionLinkの値を更新します。

最初のステップとして、APIのリストをどこから取得するかを検討する必要があります。このチュートリアルでは、SwaggerHubをリポジトリシステムとして使用し、さまざまなAPI定義を提供します。まだSwaggerHubアカウントをお持ちでない場合は、こちらから無料でサインアップし、組織を作成して、いくつかの定義を追加できます。または、このチュートリアルで提供されている例の組織を使用することもできます。

SwaggerHub組織とそこにホストされているいくつかの定義があるので、それらをポータルに取り込むことを考え始めることができます。これはすべてSwaggerHub APIによって駆動されるため、出発点として、異なるAPI呼び出しを処理し、多くのコードの書き直しを避けるために新しい関数を作成します。

  • アプリに新しいswaggerhub関数を追加します。

この関数を使用すると、いくつかの異なるレベルでSwaggerHubに呼び出しを行うことができ、今後の新しい機能をサポートするのに十分な柔軟性があるはずです。次に、「APIのリスト」を取得する方法を検討します。

SwaggerHub APIは組織に関するリクエストを許可し、その応答にはAPI名とそれらの場所へのリンクの配列が含まれており、私たちのユースケースに最適です。

swaggerhub関数を使用して、新しいgetOrganizationData呼び出しを作成しましょう。これは、組織名という単一の入力パラメータを受け取り、SwaggerHubからの応答をAPIの状態レベルのリストとして設定します。

次に、状態オブジェクトを更新してdefinitionListを期待するようにします。また、後で利用する別のキー/値ペアを追加し、2つの新しい関数をアプリケーションにバインドする良い機会でもあります。

getOrganizationData呼び出しでも組織を参照しましたが、その情報をどこにも保存していません。今後は、サブヘッダーと会社のロゴも追加したいので、この情報を保存するための設定ファイルを作成しましょう。

  • /srcディレクトリに、organization_config.jsonという新しいファイルを作成します。
  • 設定ファイルに以下のオブジェクトを追加し、組織の情報で埋めます。
  • 次に、設定ファイルをsrc/App.jsにインポートします。
  • 最後に、ページロード時にデータをマッピングするcomponentWillMount関数を作成します。

APIリストを取得するためのブロックを構築しました。次に、その情報を消費者にどのようにレンダリングするかを考え始める時です。次のいくつかのステップでは、新しいコンポーネントSidebarと、サイドバー内に配置される新しい要素apiLinkを構築します。

  • /srcに新しいファイルSidebar.jsを作成します。サイドバーは最初は非常にシンプルで、基本的な構造と設定ファイルに保存されている表示名データの一部だけです。
  • メインAppのrenderセクションで、新しいコンポーネントSidebarを含めるように更新します。この時点で、必要なデータと関数も渡すようにします。
  • Sidebarもアプリケーションにインポートするようにしてください。また、ドキュメント表示を少し整理するために、swagger-uiモジュールからCSSファイルをインポートする必要があります。これについては後でカスタマイズを検討します。
  • ブラウザで物事を少し整理するために、今後どこで何を変更しているかを明確にするための簡単なCSSを追加しましょう。App.cssファイルで、ページの構成を開始できます。

empire_nolinks.JPG

素晴らしい!サイドバーの基本的な構造(ヘッダーとリンクを保持するメインボディ)ができました。しかし、重要な部分であるリンク自体がありません。すでに必要なデータの大部分が渡されてくるpropsを通じて渡されているので、それを処理し、状態オブジェクトを更新するためのロジックを記述するだけです。

  • 新しいファイル/src/APILink.jsを作成し、サイドバーから渡されるデータを処理するために使用します。
  • ここでは、まだ渡されていないいくつかのものを要求しています。まず、App.jsにupdateDefintionLink関数を作成し、コンストラクタでバインドしてサイドバーに渡しましょう。
  • 次に、2つを接続するために、Sidebar.jsを更新して以下を含めます。

何が追加されましたか?

  • まず、組織データがロードされているかどうかを検証し、ロードされていない場合はgetOrganizationDataを使用してそのリクエストを行います。
  • APIデータが取得できたら、それを反復処理し、ユーザーの選択に基づいてdefinitionLinkコンポーネントを更新する新しい要素APILinkに渡します。SwaggerHubで「公開済み」かどうかを確認し、リンクがapiLinks配列にプッシュされます。
  • 最後に、APILink.jsから新しいインポートがあります。

完璧です。今すぐページを再読み込みすると、サイドバーにすべての異なるAPIの名前が入力されているのが見えるはずです!CSSをすばやく更新して整理しましょう。

これで、すべてのリンクが左側に表示され、クリックできるようになりました。問題が1つだけあります。ドキュメントコンポーネントが実際には更新されていません。幸いなことに、これはすぐに修正できます。現在、updateDefinitionLinkは機能しています(console.logを使用すると、URLが正しく渡されていることがわかります)。Swagger UIは、それが存在しているライフサイクル段階のために、それが更新されたことを知らないだけです。

これを修正するには、App.jsで以前のcomponentDidMount関数をcomponentDidUpdateに更新するだけで、ページを再読み込みすると、新しいリンクが選択されるたびに更新されるはずです!

example.gif


まとめ

この時点で、機能する(ただし非常に基本的な)APIドキュメントポータルができました!新しいAPIバージョンや定義を追加したり、バックエンドで公開・非公開を変更したりし続けることができます。そして、ドキュメントは常に最新の状態に保たれます。

このシリーズの次のパートでは、ドキュメントをパーソナライズするためにサイドバーとSwagger UI要素を効率的にスタイルする方法について説明し、最終パートではいくつかの異なるホスティングサイトにデプロイします。

この時点での最終的なコードは以下のとおりです。

お読みいただきありがとうございます!さらに多くのAPIリソースをお探しですか?Swaggerニュースレターを購読してください。最高のAPI記事、トレーニング、チュートリアルなどが毎月メールで届きます。 購読する