.http で簡単HTTPテストリクエスト

.http (ドットエイチティティーピー) ファイルを作ると、HTTPリクエストを手軽に送信することができます。

例えばAPIサーバを作ったなど時に、検証でリクエストを送ると思います。Webフレームワークに含まれるユニットテストは別として、任意にリクエストを発行して検証する場合は

- ウェブブラウザ
- curlコマンド
- Postmanアプリ
- Python+Requests や、JS+Axios のようなスクリプト言語

などがよく使う方法だと思います。

ウェブブラウザを使ってのテストは、ヘッダーやリクエストボディを扱うのが難しかったり、Postman や Python などは複雑な処理が行える分、実際にリクエストを発行するまで少し手間がかかり、試したい内容に比べて大仰だったりします。

.http でのリクエストは、ファイル記述が明快で、JetBrains のエディター (PyCharm , WebStorm) にはデフォルトでプラグインやテンプレートが含まれているため、素早く作って検証するのに最適です。Visual Studio Code はプラグインがありますので、それを入れると快適に使えます。

もし、APIの認証で、リクエスト内容から hmac で署名を求めてリクエストに含めるとか、jwt を扱うとか、そういった複雑な処理を含むのであれば、.http では難しいので、postman やスクリプト言語を使った方が良いと思いますが、セッションクッキーやベアラトークンでの認証や、Basic/Digest 認証程度であれば、.http がちょうどよく役に立ちます。

# .http スクリプトの文法

```
POST http://localhost/api/item
Content-Type: application/json

{"id": 99, "content": "new-element"}

###
POST http://localhost/api/item
Content-Type: application/x-www-form-urlencoded

id=99&content=new-element

###
GET http://localhost/api/item?id=99
Accept: application/json

```

1行目に メソッドとリクエストURL、2行目以降はリクエストヘッダー、空行を1つはさんでリクエストボディとなります。基本的に、これだけです。 `###` を区切りとして、複数のリクエストを1つの .http ファイル中に書けます。

### 変数展開

```
GET {{host}}/get?show_env={{show_env}}
Accept: application/json
```

`{{ 〜 }}` で変数を指定できます。変数は環境ファイルから読み込まれます。ステージングサーバと本番サーバで値を分けたい時に使います。


# 処理系・実装

https://github.com/bayne/dot-http

Google 検索すると、こちらの、bayane さんが rust で書かれているコードが出てきて、他にそれらしいのは見当たりませんので、この方が考えられたものなのでしょうか。

仕様自体は昔からあって、rust 実装は bayane さんが作られたような気がしなくもないですが、非常に検索しにくい名前のため詳細はわかりませんでした。

実際に扱うとしたら、エディタに含まれるプラグインを使う場合が多く、この dot-http コマンドをCUI から実行することはまずありません。

# JetBrains のエディタから使う

## Scratch から作る

デフォルトの状態で、Scratch から .http が作れるようになっています。

`Command + Shift + N` の、New Scratch File から、 http とタイプして HTTP Request を選択します。

![スクリーンショット 2020-12-19 21.26.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/68302/6577815b-5b23-d595-ec96-3d8129d35220.png)

空ファイルが作られますが、上に専用メニューが表示されています。このメニューから簡単にテンプレートを呼び出せます。

![スクリーンショット 2020-12-19 21.28.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/68302/0a5a1e13-ddfe-073b-8db9-dee60fc7a724.png)

Add request から GET Request を選ぶと…

![スクリーンショット_2020-12-19_21_29_54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/68302/5c4b37c3-f4bc-ae17-aaa6-aece79c6adba.png)

GETリクエストのテンプレートが呼び出されます。あとは内容を書き換えて、 ▶ をクリックすると、リクエストが発行され、結果が出力欄に出てきます。

![スクリーンショット 2020-12-19 21.31.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/68302/5931bed6-ecec-9ef9-761d-85ef715a85a4.png)

JSON を POST するリクエストなども、同様にかなり手軽に素早く作ることができます。

## 変数ファイルを作って環境ごとに異なる変数を埋め込む

ディレクトリの中に、`http-client.env.json` という名前でファイルを作ります。

```json:http-client.env.json
{
  "local": {
    "host": "http://127.0.0.1:8000",
    "sessionId": "xxxxxxxxx"
  },
  "staging": {
    "host": "https://staging.example.com",
    "sessionId": "xxxxxxxxx"
  },
  "production": {
    "host": "https://production.example.com",
    "sessionId": "xxxxxxxxx"
  }
}
```

すると、他の .http ファイルから、変数が使えるようになります。

```:request.http
GET {{host}}/api/item?id=99
Accept: application/json
Cookie: sessionid={{sessionId}}

###
```

エディタで ▶ をクリックすると、環境を選んでリクエストを発行できます。

![スクリーンショット 2020-12-19 21.43.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/68302/4c006fa6-4c75-6173-a398-da04aecca14b.png)

PyCharm で試した所、プロジェクト内にあるすべての `http-client.env.json` を探して、使えるようになってました。

### その他のリクエスト例
上部メニューの 「Examples」 に、いくつかサンプルが入ってます。記述がシンプルなので、見るだけですぐ理解できる内容となっています。

![スクリーンショット 2020-12-19 21.49.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/68302/5165a848-5a95-6856-0aee-09b924208bf1.png)

## リダイレクトを追わない

```
### GET request with disabled redirects
# @no-redirect
GET http://httpbin.org/status/301
```
デフォルトでは、リダイレクトレスポンスはそのまま GET で追従します。
`@no-redirect` を書くと、リダイレクトレスポンスがそのまま見れます。

## レスポンスのテストをする

```
### Successful test: check response status is 200
GET https://httpbin.org/status/200

> {%
client.test("Request executed successfully", function() {
  client.assert(response.status === 200, "Response status is not 200");
});
%}
```

レスポンスオブジェクトを JS で処理・検証できます。

# Visual Studio Code で使う

REST Client という機能拡張で同様のことが行なえます。

というか、調べていて思ったのですが、 `.http` という呼び名より、この REST Client の方が有名だったみたいで、 REST Client の使い方の記事が多く出てきました。結果、私のこの記事はそれらの内容の丸コピーみたいになってしまいました。

とはいえ、Advent Calender の担当分として書いちゃったのでそのまま公開します。