概要
IntelliJ IDEA Ultimate Editionにデフォルトでバンドルされている[HTTP Client] (https://plugins.jetbrains.com/plugin/13121-http-client)プラグインの使い方をまとめたメモです。
HTTP Clientを利用するとIntelliJ IDEAのコードエディターの機能を使ってHTTPリクエストを記述し、そのまま実行することができます。
※VSCodeにもRest Clientという拡張機能がありますが、それと似たような機能です。
環境
- Windows 10 Professional 20H2
 - IntelliJ IDEA 2020.1.2 Ultimate Edition
 
参考
- [HTTP client in IntelliJ IDEA code editor] (https://www.jetbrains.com/help/idea/http-client-in-product-code-editor.html)
 - [IntelliJ's text based HTTP client] (https://www.mscharhag.com/intellij/http-client)
 
はじめかた
Http Clientプラグインのインストール
HTTP Clientプラグインは、すでにインストールされているのですぐに使い始めることができます。
ただし、Community Editionでは利用できません。

HTTPリクエストファイルの作成
最初にHTTPリクエストファイルの作成を行いますが、このファイルにはスクラッチなHTTPリクエストファイルと、そうでない(通常の)HTTPリクエストファイルの2種類あります。
どちらもHTTPリクエストの書き方に違いはありませんが、それぞれ下記の特徴があります。
スクラッチなHTTPリクエストファイルの作成
※オフィシャルなドキュメントではCreate an HTTP request scratch fileと記述されているので、この記事では”スクラッチなファイル” や ”スクラッチファイル”と表記しました。
スクラッチなファイルは開発中のAPIをテストするためのものでプロジェクト外に作成され、プロジェクトとは別に管理されます。(なのでプロジェクトがバージョン管理されていてもスクラッチファイルは管理外です。)
もう1つの特徴として、HTTPリクエストを実行するとレスポンスファイルへのリンクがスクラッチファイルに追記され、実行結果(レスポンス)を後から確認できます。(詳しくは後述します)
スクラッチファイルの作成
スクラッチファイルの作成は、メニューバーのFile → New → Scratch Fileを選択するか、Ctrl + Shift + Alt + Insertを押下します。

httpと入力してメニューの絞り込みを行いHTTP Requestを選択します。

スクラッチファイルを作成する場所は選べず、図の場所にscratch.httpという名前のファイルが作成されます。
ファイルはいくつでも作成できますが、2つ目以降はscratch_1.httpのように枝番が付きます。

HTTPリクエストファイルの作成
※オフィシャルなドキュメントではCreate a physical HTTP request fileと記述されています。
HTTPリクエストファイルはプロジェクト内に作成されるので、プロジェクトをバージョン管理している場合はこのファイルも管理対象(除外していなければ)になります。
このファイルは主にAPIの文書化(仕様や使用例)を目的としているようです。
スクラッチファイルではAPIテストでHTTPリクエストを実行するとレスポンスファイルへのリンクが追記されましたが、このファイルでは追記は行われません。
ファイルの作成
ファイルの作成は、プロジェクトを(作成したいディレクトリがあればそのディレクトリを)フォーカスした状態で、メニューバーのFile → New → HTTP Requestを選択します。

ファイルの名前を入力します。この例ではapi-specとしました。

HTTPリクエストの記述と実行
HTTPリクエストの構文
HTTPリクエストの一般的な構文は下記の通りです。
Method Request-URI HTTP-Version
Header-field: Header-value
Request-Body
この中で必須のパートはRequest-URIで、その他はHTTPリクエストによって省略できる場合があります。
たとえば下記のGETリクエストの場合
GET http://localhost:8080/memo/1 HTTP/1.1
MethodとHTTP-Versionは省略できるので
http://localhost:8080/memo/1
と記述することができます。
POSTする場合はMethodは省略できないので
POST http://localhost:8080/memo
のようになります。
記述
コードエディターで直接HTTPリクエストを記述する方法の他に、エディターパネルの上部にあるAdd Requestというリンクをクリックしてテンプレートから展開することもできます。
テンプレートの種類は図の通りです。

図がGET Requestのテンプレートを展開した結果です。

テストするAPIにあわせてHTTPリクエストの記述を修正します。
この例では以下のように書き直しました。
###
GET http://localhost:8080/memo/1
Accept: application/json
###
コメント行
HTTPリクエストファイルにコメント行を記述できます。
// または #で始まる行がコメントとして扱われます。
// コメント行
# コメント行
複数のHTTPリクエストを記述する
1つのファイルに複数のHTTPリクエストを記述する場合、###で始まる行でセパレートします。
セパレートには下記のようにコメントも記述できます。
### Get memo
GET http://localhost:8080/memo/1
Accept: application/json
### Get multiple memos
GET http://localhost:8080/memo/ids/1,2,3
Accept: application/json
コード補完
HTTPリクエストの記述ではコード補完が利用できます。
例えば図のように途中まで入力し、Ctrl + Spaceを押下すると候補が表示されます。

HTTPリクエストの実行
実行は行番号の右側にある緑色のRunアイコンをクリックします。

レスポンスが画面下部のウィンドウに表示されます。レスポンスはレスポンスファイルという別のファイルに記録されていて、後述する方法でいつでも確認することができます。

スクラッチファイルの場合は、HTTPリクエストを実行すると図のようにレスポンスファイルへのリンクが書きこまれます。この行にカーソルを置いてCtrl + Bを押下するか、Ctrlを押しながらクリックすると、そのレスポンスファイルを確認することができます。

実行するたびにレスポンスファイルへのリンクがスクラッチファイルに書きこまれていきますが、書き込みが2件以上あると図のように行番号の右にコンペアアイコンが表示され

クリックするとレスポンスファイルをコンペアすることができます。(どれとコンペアするか選択します)

図がコンペア結果の画面ですが、この例はAPIがレスポンスしたJSONデータになります。

レスポンスファイルの確認
レスポンスファイルはプロジェクトの.idea/httpRequests/ディレクトリ下に作成されています。

スクラッチファイルでは、HTTPリクエストを実行するとレスポンスファイルへのリンクがスクラッチファイルに追記されますが、そのリンク先はここにあるレスポンスファイルになります。
なお、制限として直近50件分のレスポンスファイルしか保存されません。
curl記法のコンバート
もう1つの便利な機能としてcurlの記法を変換するConvert cURL requestsというリンクがあります。
クリックするとcurl記法のHTTPリクエストを入力するダイアログが表示されるので、図のように入力しconvertボタンをクリックするとHTTPリクエストに変換されます。

なお、curlのすべてのオプションをサポートはしていないので注意が必要です。(サポートしているオプションは [Convert cURL requests] (https://www.jetbrains.com/help/idea/http-client-in-product-code-editor.html#converting-curl-requests) で確認できます)
curl記法のHTTPリクエスト
curl -v -H "Content-Type:application/json" -d @memo_1.json -X POST "http://localhost:8080/memo"
変換されたHTTPリクエスト
# curl -v -H "Content-Type:application/json" -d @memo_1.json -X POST "http://localhost:8080/memo"
POST http://localhost:8080/memo
Content-Type: application/json
< memo_1.json
環境変数
環境変数を登録することができます。環境変数を管理するファイルはエディターパネルの上部にあるAdd Environment Fileというリンクをクリックして作成します。
図の通り環境変数ファイルにはRegularとPrivateの2種類あります。

Regular
for common variables such as host or query parameters.
---------------------------------------------
ホストやクエリパラメータなどの一般的な変数用
Regularな環境変数ファイルを作成するとプロジェクトルートにhttp-client.env.jsonというファイルが作成されます。上記に引用したようにホスト名やクエリパラメータなど一般的な変数を記述します。
下記は一例ですが、"dev"や"prod"が環境名でその1階層下に定義されているのが環境毎の環境変数です。
{
  "dev": {
    "baseUrl": "localhost:8080/memo"
  },
  "prod": {
    "baseUrl": "www.example.com/memo"
  }
}
Private
for sensitive data such as passwords or tokens.
---------------------------------------------
パスワードやトークンなどの機密データ用
Privateな環境変数ファイルを作成するとプロジェクトルートにhttp-client.private.env.jsonというファイルが作成されます。上記に引用したようにパスワードやトークンなどを記述します。
なお、こちらのファイルをバージョン管理したくない場合、例えばGitだと.gitignoreファイルに記述する必要があります。
{
  "dev": {
    "api-token": "jgl6H%&S0"
  },
  "prod": {
    "api-token": "Hem3k%:Q0"
  }
}
環境変数を使う
環境変数ファイルに定義した環境変数をHTTPリクエストファイル内で利用するには{{ }}というプレースフォルダを使います。
例えば、下記の書き方を
GET http://localhost:8080/memo/1
環境変数を使って書くと
GET http://{{baseUrl}}/1
となります。{{baseUrl}}の部分が環境変数になります。
実行する
環境変数ファイルが作成されていると、実行時に環境変数を選択します。

動的な変数を使う
事前定義済みの実行時に値が変わる動的な変数が3つあります。
| name | description | 
|---|---|
| $uuid | UUID v4で一意な値を生成します | 
| $timestamp | 現在のUNIX timestampを生成します | 
| $randomInt | 0から1000の間でランダムなintegerを生成します | 
GET http://localhost:8080/memo/{{$randomInt}}
その他の利用例
Cookie
Cookieの受信
HTTPリクエストを実行しレスポンスでCookieを受信した場合、レスポンス結果にメッセージが表示されます。

このメッセージの通り、受信したCookieはプロジェクトの.idea/httpRequests/http-client.cookiesというファイルに保存されています。(300件まで保存できます)
このファイルの保存されたCookieは、指定されたドメインとパスに一致するURLのHTTPリクエストに自動的に含まれます。
Cookieの送信
任意のCookieを送信するようにHTTPリクエストファイルに記述するには、下記のように構文Header-fieldにCookie:を使用します。
Cookie: key1=cookie-value-1
Cookie: key2=cookie-value-2
JSONデータをPOSTする
JSONデータを直接記述する
HTTPリクエストファイルの中にPOSTするJSONデータを記述する方法です。
下記のように構文のRequest-Body部分にJSONフォーマットの文字列を記述します。
POST http://localhost:8080/memo
Content-Type: application/json
{
  "title": "new memo title",
  "description": "new memo description",
  "done": false
}
JSONファイルをPOSTする
JSONデータが書かれたファイルをPOSTすることもできます。
下記のようにPOSTしたいファイルを<記号の後に続けて指定します。
POST http://localhost:8080/memo
Content-Type: application/json
// specify json file
< ./json/new_memo.json
上記の例では相対パスでJSONファイルを指定していますが、パスはプロジェクトルートからの相対パスになります。
画像をアップロードする
画像ファイルのPOST(アップロード)は下記のように記述します。
POST localhost:8080/upload
Content-Type: multipart/form-data; boundary=WebAppBoundary
--WebAppBoundary
Content-Disposition: form-data; name="file"; filename="demo.jpg"
< ./images/demo.jpg
--WebAppBoundary--
Response handler scriptsでレスポンスを検証する
response handler scriptsという機能があり、HTTPリクエストファイルにレスポンスを検証するJavaScriptコードを記述することができます。
スクリプトは下記のように>記号で始め、本体を{% ... %} に記述します。
GET http://localhost:8080/memo/1
Accept: application/json
> {%
// Response Handler Script
...
%}
なお、スクリプトは JavaScript ECMAScript 5.1で記述する必要があるのでconstやletといったキーワードは使用できません。
HTTP Response Handler library
- 参考: [HTTP Response handling API reference] (https://www.jetbrains.com/help/idea/http-response-handling-api-reference.html)
 
スクリプトではclientとresponseという2つのライブラリが利用できます。
レスポンスの検証
レスポンスの検証にはclient.testおよびclient.assertを利用します。
client.test("Request executed successfully", function() {
    client.assert(response.status === 201, "Response status is not 201");
});
assertが失敗するとTestsウィンドウにメッセージが出力されます。

レスポンスデータ
レスポンスデータはresponse.bodyでアクセスできます。
content-typeがapplication/jsonの場合、response.bodyにはJSONオブジェクトが格納されています。
例えば、下記のようなjsonがレスポンスされたときresponse.body.idやresponse.body.titleのようにアクセスできます。
{
  "id": 15,
  "title": "new Memo Title",
  "description": "new Memo Description",
  "done": false,
  "createAt": "2020-07-13T12:34:13.1830192",
  "updateAt": null
}
ログ出力
client.logを利用するとResponse Handlerウィンドウにログを出力することができます。
client.log("ログ出力");
レスポンスからグローバル変数をセットする
client.globalというグローバル変数を保存できるストレージがあります。グローバル変数に保存した値はHTTPリクエストの中で{{varialble_name}}というプレースフォルダで利用できます。
例えば、次のような使い方ができます。
1) 新しいデータをPOSTし、そのレスポンスデータのIDをグルーバル変数に保存
このHTTPリクエストで実行するスクリプトで、レスポンスデータのIDをグローバル変数newIdにセットします。
ここでセットしたグローバル変数は、以降のHTTPリクエスト中で利用できます。(IntellIJ IDEAを終了するまで保存されます。)
POST http://localhost:8080/memo
Content-Type: application/json
{
  "title": "new Memo Title",
  "description": "new Memo Description",
  "done": false
}
> {%
    var newId = response.body.id;
    client.global.set("newId", newId);
%}
2) 次のHTTPリクエストでグローバル変数を利用
1)でセットしたグローバル変数newIdを、このHTTPリクエストで利用します。
GET http://localhost:8080/memo/{{newId}}
Content-Type: application/json

