Insomnia(直訳:不眠症)はOSSのAPIクライアントで、元々はGreg Schierという人が立ち上げたOSSであり、2019年にKongが買収した後はKongが主体で開発している。
このAPIクライアントは以下のような特徴を持っている。
- 対応プロトコルが豊富(GraphQL, REST, WebSockets, Server-sent events (SSE), gRPC, HTTP互換)
- APIのデバッグ、設計、テストに利用できる
- CLIを使うことでリンティング(コードの静的解析)やテストをCI/CDパイプライン内で実施できる
- プロジェクトの共有
- クラウドやGitとの自動同期
ここではそれぞれの特徴は掘り下げず、Insomniaが持つSpec、Collection、Testという3つのモードをそれぞれ触って、どういう特徴を持つものかを確認する。
なお、触る際の教材としてKong Academyの"(KDLL-203) Designing & Testing APIs with Kong Insomnia"を使ったため、ここで記載する内容はそれに沿った内容となる。
本記事の要約
Insomniaの3つのモードは以下の通り。
- Spec:YAML形式でAPIの仕様を作成、編集でき、Linterや簡単な動作確認も出来る。
- Collection:Specで作成したAPIのリクエストをまとめて管理でき、BodyやHeader、認証方法などを微調整しながら動作確認出来る。様々な言語のコードにも変換出来る。
- Test:Collectionのリクエストを元にテストを実施できる。テストコードを自動生成し、カスタマイズして実行出来る。
APIの仕様を書いてしまえば実装からテストまで自動生成でき、かつその仕様作成についても補助機能を提供している、というのがInsomniaの特徴となりそう。
APIを使った実装をするなら、とりあえず使っておけレベルで便利そうだとは思う。
事前準備
Insomniaのインストール
インストーラはWindows、Mac、Linux版がそれぞれ用意されている。
Download Insomniaにアクセスすると自分のアーキテクチャにあったバイナリがダウンロードできる。
自分のアーキテクチャと異なるものをダウンロードしたい場合はReleasesから取得できる。
また、Macユーザであればbrewでもインストール出来る。
brew install --cask insomnia
インストール後、アプリケーションを起動すると以下のようなアカウントと紐づける画面が出る。

ここではGitHubと連携して進める。
連携するとE2EEのためのパスフレーズを聞かれるので設定する。

その後にサブスクリプションのプランを聞かれる。ここではFreeで進める。

なお、有料版だと認証認可、SSO連携、AIによるテスト作成支援などが使える模様。
ここに比較表があるので、興味がある人は見てみるとよい。
クライアントアプリを立ち上げ直し、GitHubのSSOでログインする。
学習用サンプルの導入
今回は試すことが主目的なので、1から作らずに出来合いのものを使って試していく。
ここではKongの学習教材のリポジトリkong-edu-insomniaにあるBanKongという仮想の銀行サービスを使う。
これを手元にcloneしておく。
git clone https://github.com/imurata/kong-edu-insomnia.git
cd kong-edu-insomnia
サンプルの中のBanKongサービスを起動する。Docker daemonが稼働している必要があるので注意。
docker compose -f ./bankong/docker/docker-compose-bankong-combined_local_portchange.yaml up -d
起動した後にhttp://localhost:29080にアクセスするとフロントエンドのWebサービスが確認できる。
また、http://localhost:3000にアクセスするとバックエンドのサービスが確認できる。
検証
最初に新しくProjectを作成する。
Filterの右横の+をクリックする。

BanKongというProjectを作成する。ここではCloudを使わない形で進めたいのでProject typeはLocal Vaultで進める。

空のProjectが作成された後、先程cloneしたリポジトリ内にあるProjectを取り込む。
Projectの取り込み方法は以下のいずれかから選択する。

ここではImportで進める。
ImportではInsomnia、Postman、Swagger、OpenAPI等様々なフォーマットのAPIを取り込む事が出来る。
cloneしたリポジトリ内にOpenAPIで定義されたYAML(./bankong/openapi/bankong-v1.0.5.yaml)があるのでこれを読み込む。
以上で準備はOKなので、InsomniaのSpec、Collection、Testの各モードを検証していく。
Specモード
SpecモードではAPIの仕様の編集・確認を行う事ができる。
Importして表示された項目をクリックし、上のSPECをクリックすると仕様が表示される。

なお、右側にPreviewが表示されているが、表示させたくない場合は左サイドバーのSPECの横の👁🗨Previewをクリックすれば非表示に出来る。
また、Preview画面からは実際にAPIを発行することも出来る。

エディタ側に戻ると、⚠マークが出ているのが確認できる。
InsomniaにはLinterも備えていて、問題箇所を自動的に指摘してくれる。

ここでの指摘内容は以下となっている。
- info内にcontactが含まれない
- servers.urlの末尾がスラッシュで終わっているが、スラッシュは不要
- getやpostで使っているタグの定義がGlobalに存在しない
それぞれ修正すると、以下のようにNo lint problemsと表示されて警告表示が消える。

このような感じでSpecモードではAPIの仕様を編集・確認することが出来る。
Collectionモード
SPECの横のギアマークからGenerate collectionをクリックすると、Specの内容を元にAPIリクエストのセットがCOLLECTION内に作成される。

COLLECTIONに移動しそれぞれのリクエストを見ると、上部に_.base_urlや_.idのような赤くハイライトされた表示が確認できる。

これは環境変数であり、現在はbase_urlと_.idいう環境変数がColletion内で利用しているにも関わらず定義されていないため警告表示となっている。
環境変数は左サイドバー内のBase Environmentの右のギアマークをクリックすると、Manage Environmentという画面に遷移し、ここで設定することが出来る。
Manage EnvironmentでBase Environmentの右の+をクリックすると、Shared environmentとPrivate environmentの選択肢が表示される。

これはそれぞれ以下の意味となる。
-
Shared environment: Export可能な環境変数 -
Private environment: Export出来ない環境変数
名前の通り、共有するかどうかで使い分けると良さそう。
ここではShared environmentで環境変数を定義する。
OpenAPI envの環境変数をコピーし、base_url: {{_.host}}を追加する。
idについては個別のトランザクションを指定するためのもので、http://localhost:3000/transactions/にアクセスすると登録済みのトランザクション全件が閲覧でき、個別のトランザクションについてはhttp://localhost:3000/transactions/$idで閲覧できるようサンプルのサービスが用意されている。
ここでは最初から登録されている143aadce-f995-4503-ba6e-01ed01c6af88を設定した。
また、新規作成した環境変数には名前をつけられるので、ここではlocaldevとした。

Collectionの画面に戻って、GETのGet Specific transactionからSendを実行すると以下の右側のような感じでレスポンスコードとBodyを取得できる。

また、POSTのCreate new transactionから新しいトランザクションを作ることも出来る。
POSTの際はボディのフォーマットをJSONからYAML等に変更したり、認証方法をAPIキーだけでなくBasic AuthやOauthに変更することも出来る。
またクエリやヘッダーも編集出来るので、確認したい内容によって書き換えると良さそう。

Patchの実装
上記のPOSTを実行するとID:42のトランザクションが生成されるが、これを以下のようの変更したい。
{
"id": 42,
"source": "GR872659435350353",
"senderName": "Max Mustermann",
"destination": "DE8412325587359375895",
"amount": 42,
"currency": "EUR",
"subject": "Invoice #42-08/15"
}
{
"id": 42,
"source": "GR872659435350353",
"senderName": "Max Mustermann",
"destination": "DE8412325587359375895",
"amount": 100,
"currency": "USD",
"subject": "Invoice #42-08/15"
}
これを行うために、Patchを実装する。
Specモードに切り替えエディタ画面を確認すると、89行目から114行目にpatchの実装がコメントアウトされていることが確認できる。
これをアンコメントする。
VSCodeと同じショートカットが使えるので、Macの人は選択してCommand+スラッシュ、Windowsの人はCtrl+スラッシュでアンコメント出来る。
なお、patch:のインデントの位置が少しずれているため赤い波線が出る。
patch:の前のスペースを1つ消せば正常な位置になる。
正常にpatchが追加できれば、PATHSのところにPTCHとPatchが表示されるようになる。

次にCollectionモードに戻り、Patchのリクエストを追加する。
自動生成機能を使う場合、SpecモードでSPECの右のギアマークからGenerate collectionをクリックすると生成できるが、今回は手動で生成する。

Collectionモードで左サイドバーのTransactionの右の▽をクリックしてHTTP Requestを追加する。

名前をNew RequestからPatch a transactionに変更する。
次に画面上部のGET ▽となっているところをクリックしてPATCHに変更する。
次にその横のパスを指定する。ここでアンダースコア(_)を入力すると自動で候補が出てくるので、Patchを当てる対象となるトランザクションである{{ _.base_url }}/transactions/{{ _.id }}を選択する。
ただ、idはlocaldevのものを引っ張ってきているので、URL PREVIEWにはhttp://localhost:3000/transactions/143aadce-f995-4503-ba6e-01ed01c6af88が表示され、書き換える対象は先程Postしたものと異なってしまう。
そのためここでは一旦ベタ書きでidを上書きし、42を指定する。

次にBodyのタブを選択してJSON形式で上書きする内容を記入する。
{
"id": 42,
"source": "GR872659435350353",
"senderName": "Max Mustermann",
"destination": "DE8412325587359375895",
"amount": 100,
"currency": "USD",
"subject": "Invoice #42-08/15"
}
以上でPatchの準備が整ったので、SendをクリックしてPatchを当ててみる。
適用後、GETのList all transactionsで変更後の値を確認すると書き換わったことが確認できる。
問題なければ、ここで確認した内容をコードにすることが出来る。
リクエストの横の▽をクリックすると、Generate Codeというのが選択できる。

選択後、 言語やライブラリを選択すると、以下のような感じでコードが出力される。めちゃくちゃ便利。

Testsモード
TestsモードではCollectionにあるリクエストを使ってテストを行うことが出来る。
まず、上部のTESTSをクリックしてTestsモードに切り替え、左サイドバーのNew test suiteをクリックし、新規作成されたテストスイートの名前をUnit Test Suiteに変更する。
次に上部のNew testをクリックする。するとReturns 200と書かれたテストの雛形が作成される。

ここでは全てのトランザクションを取得するリクエスト(GETのList all transactions)のテストを作成する。
まず作成したテストの雛形の名前をList All Transactions Returns 200に変更する。
次に、横のSelect a requestをクリックすると、Collection内のリクエストの一覧が表示されるので、GETのList all transactionsを選択する。
作成後、更に右にある再生ボタン(▷)をクリックすると、テスト結果が表示される。

クリックするとテストコードが確認できる。
const response1 = await insomnia.send();
expect(response1.status).to.equal(200);
なお、テストコードはJavaScriptのテストフレームワークであるMochaとChaiで書かれている。詳細はこちら。
同じようにGet Specific Transactionも追加して確認する。

せっかくなので少しテストをカスタマイズしてみる。
Get Specific TransactionのBodyをチェックするように書き換える。
const response1 = await insomnia.send();
expect(response1.status).to.equal(200);
const body = JSON.parse(response1.data);
expect(body).to.have.all.keys('source', 'senderName', 'destination', 'amount', 'currency', 'subject', 'id');
これでテストを再度実行すると、やはりPassedとなる。
テストに失敗するよう、'id'を消してみると以下のようにテストに失敗した。

このように、TestモードではAPIのテストを作成・管理できることが確認できた。
所感
要約のところにも書いたけど、設計からテストまで一通り補助する機能があるのは非常に便利。
特に自動生成周りは初めて開発する人のハードルを下げてくれるので、特に慣れたツールとかなければ使ってみるとよいかと思う。
今回はCLI周りは触れなかったが、機会があれば触ってCI/CDパイプラインに組み込んでみたいと思う。