QiitaのAPIを題材にInsomniaを使ってみる

前回、「[Insomniaの3つのモードを触ってみる](https://qiita.com/ipppppei/items/cc33db7772886b9d0946)」という記事を書いたが、サンプルが最初からある程度作り込まれていたので、なぞってる感が強かった。
また、コンテナ環境が必要だったので人によってはハードルが高かったかもしれない。
今回は[QiitaのAPI](https://qiita.com/api/v2/docs)を題材にして、コンテナ不要、API仕様も作るところから確認して、ゼロベースで使い始めた場合どんな感じになるかを確認してみる。
なお前提として、[Insomnia](https://docs.insomnia.rest/insomnia/install)が既にインストール済みであるものとする。


## プロジェクトの作成からAPI仕様の作成まで
Insomniaを立ち上げて、左サイドバーの`PROJECTS`の`+`を押して新規プロジェクトを作成する。
ここではQiitaAPIという名前にし、Localに保存する設定で作成した。
![1710130897014.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547981/10065182-e7d0-2dc6-edbf-7ba737ea59c5.png)

次に`New Document`をクリックしてドキュメントを作成する。
`Create New Design Document`というダイアログが表示されるので、デフォルトの`my-spec.yaml`のまま`Create`をクリックして空のSpecを作成する。

次に[OpenAPIの仕様](https://spec.openapis.org/oas/latest.htm)に従ってSpecを作成する。
（ただ、OpenAPIの仕様に関しては[QiitaのOpenAPIのタグ](https://qiita.com/tags/openapi)にまとまったいい感じの記事がいくつかあるので、仕様書をガッツリ読むよりはこちらをかい摘んで理解した方が学習効率は良さそう）
QiitaのAPIの仕様は[ここ](https://qiita.com/api/v2/docs)にまとまっている。
ここでは記事の取得（**/api/v2/items**, **/api/v2/items/:item_id**）と認証中のユーザー情報取得（**/api/v2/items/authenticated_user**）を実装してみる。
試しに書いてみたAPI仕様のYAMLが以下となる。
```yaml:my-spec.yaml
openapi: 3.1.0
info:
  contact:
    name: hoge
  version: 0.1.0
  title: Qiita API
  description: | 
    Testing with Qiita API 
servers: 
  - url: https://qiita.com/api/v2
    description: Qiita API Endpoint  

security:
- Bearer: []

tags:
- name: qiita
  description: Qiita API
  externalDocs:
    url: https://qiita.com/api/v2/docs

paths:
  /items:
    get:
      description: Get items
      summary: Get items from Qiita
      tags: ["qiita"]
      operationId: "getitems"
      responses:
        "200":
          description: Succeeded to get items 
  /items/{item_id}:
    get:
      description: Get specific item
      summary: Get specific item from Qiita
      tags: ["qiita"]
      operationId: "getitemsid"
      responses:
        "200":
          description: Succeeded to get items 
      parameters:
      - name: item_id
        in: path
        required: true
        description: The transaction id.
        schema:
          $ref: "#/components/schemas/item_id"
  /authenticated_user:
    get:
      description: Get user info
      summary: Get user info from Qiita
      tags: ["qiita"]
      operationId: "getuserinfo"
      responses:
        "200":
          description: Succeeded to get user info 

components:
  schemas:
    item_id:
      type: "string"
      description: "Item ID"    
      example: "cc33db7772886b9d0946"
  securitySchemes:
    Bearer:
      type: http
      scheme: bearer
      description: Credentials or access token for API
```
問題なければ、以下のような感じで表示される。
![1710134721819.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547981/0d2bea4a-6a0f-ff2e-2c4e-8bcd8e248514.png)

下に`No lint problem`と表示されれば記載については問題ない。
また、右の仕様の画面で`GET`のところから実際にAPIを発行することが出来る。
なお、認証に関しては設定していない場合、以下のように401が返ってくる。
![1710134954152.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547981/b61e5bdd-f709-5267-58b1-ed18cf758800.png)
認証部分はBearer（トークンによる認証）にしているので、トークンを取得してInsomnia上で設定しないと200にならない。
トークンはQiitaのアカウントがあれば[ここ](https://qiita.com/settings/applications)から発行できる。
トークン発行後、InsomniaのAPI仕様の画面の上部にある`Authorize`をクリックし、出てくるダイアログにトークンを貼り付けて`Authorize`をクリックすると認証した状態になる。（ダイアログは自動で閉じないので`Close`をクリックして閉じる）
その状態で再度実行すれば成功するようになる。
![1710135245902.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547981/2542d488-72eb-d97c-c654-3c8c22c6216f.png)

## Collectionによる動作確認
先ほどまでの手順で動作確認は出来たが、以下のようなことが出来なかった。
- item_idを変えての動作確認
- 認証トークンの保持

ここではInsomniaのCollectionという機能を利用してよく投げるAPIのセットを定義する。
Collectionは自動生成機能があるので、まずこれを使ってベースとなるCollectionを作成する。
SPECの右のギアマークをクリックし、`Generate collection`をクリックする。
![1710135822368.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547981/af672578-3b9a-0d35-7be0-df57c8129b03.png)

すると、作成したリクエストごとに雛形が作成される。
ただ、可変部が`_.base_url`や`_.item_id`といった名前で変数化されており、このままでは利用できない。
![1710135943887.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547981/98933a35-86ce-eb38-93b5-82c93d2f1b4f.png)

これらは環境変数として定義できるため、それぞれ定義する。
`Generate collection`でCollectionを作成すると、自動的に環境変数の箱が定義されるので、そこに追加する。
左上の`Base environment`の横のギアマークをクリックする。
![1710137337361.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547981/8ae7efc2-8c71-4edd-e8e2-a0f83272e18f.png)

環境変数の一覧が表示されるが、ここで`OpenAPI env qiita.com`というのがShared（他のプロジェクトメンバーと共有される）な環境変数として用意されていることがわかる。
これが`Generate collection`で追加された環境変数である。
この中の、`scheme`, `base_path`, `host`は全環境で共通化できるのでコピーして`Base Environment`（全Collectionで共通の環境変数）に記載する。
また`base_url`はそれらの環境変数で定義できるため、環境変数を使って定義する。
```json:Base Environment
{
	"scheme": "https",
	"base_path": "/api/v2",
	"host": "qiita.com",
	"base_url": "{{ _.scheme }}://{{ _.host }}{{ _.base_path }}",
}
```
なお、`{{...}}`の部分は`._`と入力すると候補が出てくるので、こういう書き方をしなくてもインタラクティブに入力することも出来る。
また、トークンは共有しない方がいいので、Privateな環境変数を別で作成する。
`Base Environment`の右横の`+`をクリックし、Privateな環境変数の箱を作成し、`myenv`とリネームする。
中には以下のようにトークンと`item_id`を定義する。
```json
{
	"bearerToken": "567xxxxxxxxxxxxxxxxxx",
	"item_id": "bf1a1aa9f2a609864e7e"
}
```
これで`myenv`を選択して`GET _.base_url/authenticated_user`にアクセスするリクエストを投げると以下のように200を取得することが出来る。
![1710138610456.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547981/b66d77db-799c-ddea-3c0a-f67f4e015042.png)

## テストの作成
最後にテストを作成する。上部の`SPEC` `COLLECTION` `TESTS`の並びから`TESTS`をクリックし、画面遷移後に`New test suite`をクリックするとテストスイートが作成できるので、`Qiita Test Suite`という名前にリネームする。
テストスイート作成後、`+ New test` をクリックするとテストの雛形が作成される。

![1710204883870.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547981/a4c6b602-5105-4e4f-d595-8295027d80f0.png)
`Select a request`をクリックすると、Collection内のリクエストが選べるので、テスト対象を指定する。
ここではCollection内のリクエストそれぞれに対応する3つのテストを用意する。

![1710204955957.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547981/c899775f-7cad-464a-57ac-68844a864e50.png)

テストを実行すると、おそらく全て問題なくPassするはずだ。
![1710205010270.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547981/f3691e26-1792-70a3-d49d-eaae5d783547.png)

試しに環境変数`myenv`内の`bearerToken`を不正なものに書き換えて実行する。
![1710205094705.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547981/c23b0c0c-faf0-0c3a-a41d-c0108257fb0a.png)

失敗した。
なお、失敗した要因を確認したい場合はデバッグウィンドウを表示させるとよい。
`View`->`Toggle DevTools`をクリックすると、右にChromeのデバッグウィンドウが表示される。
![1710206132353.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547981/1340b04f-c30f-cb3e-51f0-19ab8d8e6591.png)

`console.log()`を使うとConsoleのところに任意の文字列を出したりすることが出来る。
`expect()`の前に`console.log()`でresponseの中身を除くようコードを変更する。
```javascript
const response1 = await insomnia.send();
console.log(response1);
expect(response1.status).to.equal(200);
```
実行した結果がこちら。
![1710206394655.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547981/28127077-f0d7-008a-093a-67ecb3337c75.png)

401の詳細が確認できた。

ということで、Insomniaを気軽に触って体験してみたい人は、とりあえずInsomniaをインストールして、身近なAPIを題材に触ってみると良いと思う。