VS Code用SwaggerHub:開発者のニーズがAPI設計のためのクールな新しい拡張機能になった経緯

  2020年11月06日

SwaggerHubを使うことの最も素晴らしい点の一つは、APIに触れる機会が多いことです。APIはどこにでもあります!私たちは、自分たちが使っているAPIを文書化するためのアプリケーションを書くために、APIを自分たち自身で使っています!私はSwaggerHubのフロントエンド開発者なので、APIに触れる機会は主に消費者として訪れます。私は、ファーストパーティユーザーとして、APIの結果を形作る手助けをしています。

さて、フロントエンド開発者として、私が選ぶIDEはVisual Studio Codeです。高速で整然としており、JavaScript開発者にとっては、JavaScriptで書かれているという点も非常に便利です。何か不明な点があれば、オープンソースの内部を覗いて、何が動いているのかを確認することができます。

これらはすべて、このブログの核心であるVS CodeとSwaggerHubへの前置きです。ご存知のように、SwaggerHub APIを使用するSwaggerHubのフロントエンド開発者として、私は当然、VS CodeでそれらのAPIを読み、使用し、作業したいと考えます。しかし、それはこれまで常に面倒なことでした。

コンテキストを失いたくない場合、YAMLをダウンロードし、エディターで開くと、すぐに同僚の開発者が行った変更と同期が取れなくなってしまいます。この方法はすぐに断念し、SwaggerHubを1つの画面で、VS Codeを別の画面で開いたままにするようになりました。

これは機能的ではありましたが、常にもっと良い方法があるはずだと考えていました。そこで、毎年開催されるハッカソンのアイデアをブレインストーミングしているときに、この2つを組み合わせて、SwaggerHubと完全に統合するVS Codeの**拡張機能**を書くのはどうかと思いました。

SwaggerHubアカウントを持っている人なら誰でも利用できる公開APIがすでにありますので、それをIDEに組み込むのはどうでしょうか。当時、VS Code APIはハッカソンのために理解するには少し複雑すぎるように思われました(後になって、その通りだったと分かりました)。そのため、そのイベントではこのアイデアは実現しませんでした。しかし、それはずっと温めていました。

SwaggerHubでは、新しい機能を構築する必要が常にあるため、ダウンタイムがあることは稀です。しかし、あるスプリントで、数日間、個人的なプロジェクトに取り組む時間が与えられました。一種のミニハッカソンです。私たちのほとんどは、SwaggerHubを改善したいという小さな情熱的なプロジェクトや改善点を持っていますが、時間を得ることはめったにありません。ですから、機会が訪れたとき、私は両手で掴み、仕事に取り掛かりました。

当社の公開APIのおかげで、機能の多くの境界は既知であり、APIで利用可能なものしか構築できません。これらの制約から、拡張機能が提供できる機能の種類はすぐに明らかになり、最初に取り組む必要があったのは、SwaggerHubの核となるもの、つまり組織、API、ドメインをどのように表示するかでした。

ツリービュー

VS CodeのUIは厳格で統一されています。この厳格さは、拡張機能が予測可能で信頼できる方法で機能するため、VS Codeの最も優れた点の1つです。UXは常に難しいものですが、VS Codeにおける拡張機能設計の確立された言語は、論理的に配置すれば、エンドユーザーは既存の設計言語に頼ることでそれを見つけやすくなることを意味します。

左側にはTreeViewコンテナがあります。これは、拡張機能の主要なアクティベーション要素がすべて含まれているバーです。次に、補助的な拡張機能が格納されているTreeView自体があります。そして最後に、メインエディタがあります。組織、API、ドメインのリストを提供する論理的な場所は、ファイルブラウザのツリー構造を模倣したスタイルのTreeView内でした。

VS Code APIは最初は威圧的ですが、時間が経つにつれて徐々に分かりやすくなります。作業している機能によっては、ドキュメントの明確さが大きく異なる場合があります。API自体は明確ですが、機能の説明は曖昧な場合があり、その多くは既存の例で構成されています。これらは簡潔にしようと努めていますが、API全体から多くの機能が混ざっています。重要だと思っていたことを実装してしまうこともありますが、実際にはそうではありませんでした。

私たちの目的のためには、階層的なリスト、つまりフォルダー、ドキュメント、バージョンを「API」セクションと「ドメイン」セクションに分けて表示する必要があることは明らかでした。

TreeViewの初期化は簡単です

新しいTreeViewを作成し、それらのプロバイダをグローバルオブジェクトにバインドして、アプリケーション全体で参照できるようにします。プロバイダ自体は、コア機能を囲むクラスラッパーです。APIとドメインの間には区別があり、それらが唯一の区別であるため、簡略化のためにブール値をコンストラクタに渡します。

ここで重要なのは、onDidChangeTreeDataイベントです。これは、より多くのデータをプルダウンしたいときに、TreeViewを更新するために発生させることができるイベントです。

次に、データをTree Viewに投入します。APIを使用する組織は、設定で文字列の配列として定義されていますが、非同期アクションが必要な小さなメッセージングがその周りにラップされています。

APIリストの生成は簡単です。組織を取得し、定義メタデータをプルして、データセットを巡り、ツリーを構築します。

ツリーブランチの葉を順次構築することは、当然ながら高速で簡単です。また、フラット化された結果を返すことで、TreeViewは利用可能なすべてのAPIとドメインを表示するために必要な完全なデータセットを得ることができます。

コンテキストメニュー

VS Codeを使って作業するということは、常に新しい遊び相手を見つけるということです。ツールのほぼすべての側面には、何らかの拡張機能を追加したり利用したりできます。ステータス更新機能(可視性の変更、公開/非公開など)を含める時期が来たとき、最初の方法は単にコマンドパレットを利用することでした。

これは、直接的な1対1のUIを持たないほとんどの拡張機能の伝統的な場所であり、基本的にはVS Codeのコマンドラインです。しかし、この機能にはコマンドパレットよりも優れたUXがあるはずだと私は考えました。VS Codeで拡張機能を構築する作業の多くは、すべてがどこにあり、なぜそこにあるべきかを理解することです。コマンドパレットは最後の手段であり、非常に「とりあえずこれで間に合わせる」というような状況だと私は考えています。

私がかなり前から追跡していたスレッドは、エディターの右クリックメニューにサブメニューを追加することについてでした。フライアウトサブメニューは、要素を配置するのに最適なコンテキスト上の場所となるはずでした。APIが利用可能であればの話ですが。オープンソースのVS Codeリポジトリでこれについて言及している最初のスレッドは2016年のものです。https://github.com/microsoft/vscode/issues/9827。これは明らかに有用で必要な機能であり、このUXの困難を解決してくれるはずでしたが、明らかに事態はあまり進展していませんでした。

2020年9月の1.50.0リリースで、サブメニューAPIがついに利用可能になりました。最初の要求から4年後です。SwaggerHub拡張機能にとって完璧なタイミングでした!

新しいAPIは分かりやすかったため、更新の実装は簡単でした。

まず、一意のIDを持つサブメニューセクションを確立する必要があります。

次に、メニューの貢献ポイント内にそのIDに関連するセクションを作成します。

メニューを表示するタイミングを示すロジックを追加します。たとえば、YAML以外では表示したくありません。そして、項目をセクションごとにグループ化します。項目が独自のセクションにある場合、すべてを読みやすくするためにセパレータが自動的に追加されます。

次に、メニューを適切な貢献ポイント、この場合はエディター/コンテキストにバインドするだけです。

このような場合に私が好きなのは、ノイズを減らすためにコマンドパレットにオプションが表示されないようにすることです。これは、コマンドをcommandPalette貢献ポイントに「when」の値を「false」にして追加するだけで簡単にできます。

コマンドパレットにアクションが表示されないようにすることには、長所と短所があります。UIに機能がある場合、ユーザーは明確なパスをたどることができます。しかし、コマンドがコマンドパレットにある場合、キーの組み合わせで何でもできる「パワーゲーマー」的な雰囲気があります。

人々が使い始めると、将来的にはこれを改善していくことでしょう。ソフトウェア開発で最もエキサイティングなことの一つは、人々があなたのソフトウェアを予想もしなかった方向に引っ張ろうとするときです。この拡張機能も今後多くのそうしたことが起こるでしょう!

プレビュー

API開発の半分はAPIを書くことですが、もう半分は消費者がどのように機能するか、どのように読み書きされ、配布されるかを探ることです。SwaggerHubでは、Swagger Open Sourceの友人が素晴らしいSwagger UIプロジェクトを開発しました。https://github.com/swagger-api/swagger-ui/

SwaggerHubでは、このプロジェクトと関連するSwagger Editorを使用して、API開発プラットフォームを強化しています。これらは信じられないほど強力なツールであり、検証および表示エンジンは最高レベルであるため、これらを組み込むことを非常に嬉しく思います。私もこの優れた機能を拡張機能にもたらし、VS CodeでSwagger UIの力をユーザーに提供することで、API開発をより高いレベルに引き上げたいと思いました。

私の最初の選択肢は、VS CodeのWebView APIを使用することでした。これは実質的に、パネル内にHTMLコンテンツを表示し、外部の世界とカスタムUXへのアクセスを可能にする方法です。ここには多くの可能性があり、Swagger UIをレンダリングするための素晴らしい方法に見えました。Swagger UI npmライブラリをネイティブに持ち込み、VS Code内で魔法のように機能させるというアイデアも頭をよぎりました。しかし、最も抵抗の少ない道が最善の策であるように思われました。それに、Swagger UIにはこのような状況のためのスタンドアロンバージョンがあります。

当初は可能性の多さに圧倒されましたが、WebViewコンテナの確立に関する非常に優れたドキュメントが私を正しい道に導いてくれました。https://vscode.dokyumento.jp/api/extension-guides/webview

外から見て、静的にロードできるHTMLラッパーページを作成し、Swagger UIのJSファイルを外部からプルする必要があることに気づきました。サードパーティのインストールに関するSwagger UIのドキュメントに従って、最初の方法はunpkgを使用することでした。https://github.com/swagger-api/swagger-ui/blob/master/docs/usage/installation.md

これは簡単に機能しましたが、ウィンドウを開いてリモートファイルをプルする際の遅延が問題になりました。WebViewインスタンスが最初に作成およびロードされたときに、ライブラリがロードされる前に変換された仕様JSONがWebViewにパイプされるというタイミングの問題が発生する可能性がありました。タイミングの変更や、ロードメッセージなどを待つための調整を試しましたが、最終的には、初期拡張機能サイズは増加するものの、パフォーマンスやタイミングの問題をすべて排除できる静的ロード方法を採用することにしました。

まず、プレビューパネルを初期化します。

次に、静的フォルダーにバンドルしたJavaScriptファイルについて、VS Code互換のURIを生成する必要があります。

VS Codeの拡張機能は.VSIXファイル(実質的には豪華なzipファイル)で提供され、コードベースのごく一部しか含まれていません。webpackを使用してコア拡張機能を単一のファイルにバンドルしますが、静的リソースは静的フォルダーに格納されます。これらのフォルダーの場所はマシンごとに異なるため、各アセットに対してVS Code固有のURIを生成する必要があります。これらのURIは、その後、任意のスクリプトまたはスタイル呼び出しで使用できます。

URIを生成したら、静的に保存されているインデックスファイルを読み込み、埋め込まれたバンドル文字列({{ }}で簡単に確認できます)を新しいVS Code URIに置き換える必要があります。次に、結果として得られた変更済みインデックスをwebview.htmlにパイプし、これでSwagger UIはディスクから即座にロードできるようになります。

WebViewとの間でメッセージを投稿するためのVS Code APIは素朴ですが機能的であるため、プレビューウィンドウに仕様を渡すことも非常に簡単です。

previewWindowハンドルとコンテンツが他の場所からアクセスできるようにグローバルオブジェクトとして保存されている場合、postMessageを使用するだけで済みます。

まず、優れたjs-yamlライブラリ(業界全体が広く依存しているもの)を使用してYAMLをJSONに変換し、それをパイプする必要があります。

反対方向では、WebViewパネルがメッセージを受信するように設定する必要があります。これはイベントリスナーを設定するだけで簡単にできます。

setStateコードは、インデックス内の他の状態管理コードの続きで、プレビューウィンドウがバックグラウンドに移動しても、最後に見たスペックを保持できるようにするものです。

メッセージを受け取ったら、そのままスタンドアロンのSwagger UIに送信します。

次に、テキストドキュメントが変更されるたびにこのメソッドをトリガーすることで、エディターからSwagger UIのライブ更新を可能にします。

更新したいドキュメントだけを更新することが重要です。そのため、テキスト変更メッセージが適切な場所から来ていることを確認し、ドキュメントのテキストを取得して更新します。簡単ですね!

拡張機能には他にも多くの機能があります!しかし、これらは途中で興味深かった小さなことのいくつかです。この拡張機能の開発は、VS Codeでの構築という点だけでなく、私たち自身のAPIを使用するという点でも素晴らしい経験でした。「自社の製品を使う」ことを強く信じています。

チケット、リクエスト、戦略など、さまざまなインプットに対応して開発を進めていると、エンドユーザーエクスペリエンスを見失いがちです。アイデアから展開までの道のりは長く、ユーザーの生活を本当に体験しなければ、見落としやすいことがたくさんあります。

サードパーティの視点からAPIを積極的に使用する中で、APIを改善し、途中のニュアンスを修正するために追加の措置を講じてきました。VS Code拡張機能には姉妹プロジェクトがあります。コマンドラインインターフェースを介してSwaggerHub APIと同様の量の相互作用を可能にするCLIツールです。CI統合に非常に便利です!https://github.com/SmartBear/swaggerhub-cli

私たちは一緒にAPIを徹底的にテストしてきました。これにより、より多くの人々が私たちのAPIを使用し、SwaggerHubをより深くシステムに組み込むことを願っています。ここにはまだ探求すべき多くの可能性があり、完成次第リリースする準備ができている機能もすでに活発に開発中です。

この拡張機能の作成は愛情を込めた骨の折れる作業であり、世界と共有し、フィードバックを得ることを非常に楽しみにしています。これは長い道のりの第一歩であり、人々がこの拡張機能をどのように使用し、既存のワークフローをどれだけ変えるかを見るのが本当に楽しみです。

VS Code用SwaggerHubの新しい拡張機能の詳細を確認したり、コピーをダウンロードしたりするには、Visual Studio Marketplaceをご覧ください。

© . This site is unofficial and not affiliated with Swagger.