curlに変わる便利コマンドHTTPieを使ってみた

こんにちは。エクセルソフトの田淵です。

人のデモを見て新しいツールを知るのはとても楽しいですね。

LinuxのシェルのHttpClientといえば`curl`ですが、今日見たデモで`http`というコマンドですごく直感的にアクセスしていて、取得した情報の標準出力もシンタックスハイライトされて素晴らしかったので、そのコマンドについて紹介します。

[HTTPie](https://httpie.org/)です。

### HTTPieとは

![curl vs HTTPie](https://httpie.org/static/img/httpie2.png?v=72661be530fde9d07e03be9df60312da)

画像[https://httpie.org/](https://httpie.org/)公式サイトより

特徴として以下があります。

- 標準でいい感じ
- 直感的でいい感じのコマンド公文
- シンタックスハイライトされた標準出力
- ビルトインでJSONをサポート
- 永続的なセッション
- フォームやファイルアップロード
- HTTPS、プロキシ、認証をサポート
- 任意のリクエストデータとヘッダーをサポート
- Wgetライクなダウンロード
- 拡張機能
- Linux、Mac OSX、Windowsをサポート

### インストール

#### macOS

[Homebrew](http://brew.sh/)

```bash
$ brew install httpie
```

または[MacPorts](https://www.macports.org/)

```bash
$ port install httpie
```

#### Linux

##### Debian、Ubuntuなど

```bash
$ apt-get install httpie
```

Fedora、CentOS、RHELなど

```bash
$ yum install httpie
```

#### Windowsその他

Pythonのパッケージ管理システム[pip](https://pip.pypa.io/en/stable/installing/)を使用します。

```bash
$ pip install --upgrade pip setuptools

$ pip install --upgrade httpie
```

### HTTPieを使ってみる

Hello World

```bash
$ http httpie.org
```

httpie.orgはなぜか301を返すようで、`301`が返ってくれば成功です。シンタックスハイライトされていて見やすいですね！

```bash
HTTP/1.1 301 Moved Permanently
CF-RAY: 36c2f9ffc4692e15-NRT
Cache-Control: max-age=3600
Connection: keep-alive
Date: Fri, 09 Jun 2017 09:13:43 GMT
Expires: Fri, 09 Jun 2017 10:13:43 GMT
Location: https://httpie.org/
Server: cloudflare-nginx
Transfer-Encoding: chunked
```

![httpie002.png](https://qiita-image-store.s3.amazonaws.com/0/32453/e2cd90a4-25d1-4ec8-9642-54db0198da87.png)



HTTPのメソッドも簡単に使えます。`HTTPie`は標準で`Content-type: application/json`を指定するため、特にAPI Serverにアクセスする際は便利な気がします。
例えばPOSTする場合は例えば次のように記載します。この例では擬似（？）APIを提供する[httpbin.org](http://httpbin.org)を使用します。

```bash
$ http POST http://httpbin.org/post X-API-Token:123 name=John
```

`X-Api-Token`はきちんと`headers`に入り、`"name":"John"`が`data`としてPOSTできてるのが分かりますね。

```bash
HTTP/1.1 200 OK
Access-Control-Allow-Credentials: true
Access-Control-Allow-Origin: *
Connection: keep-alive
Content-Length: 471
Content-Type: application/json
Date: Wed, 14 Jun 2017 03:05:16 GMT
Server: meinheld/0.6.1
Via: 1.1 vegur
X-Powered-By: Flask
X-Processed-Time: 0.000705003738403

{
    "args": {}, 
    "data": "{\"name\": \"John\"}", 
    "files": {}, 
    "form": {}, 
    "headers": {
        "Accept": "application/json", 
        "Accept-Encoding": "gzip, deflate", 
        "Connection": "close", 
        "Content-Length": "16", 
        "Content-Type": "application/json", 
        "Host": "httpbin.org", 
        "User-Agent": "HTTPie/0.9.2", 
        "X-Api-Token": "123"
    }, 
    "json": {
        "name": "John"
    }, 
    "origin": "219.106.251.57", 
    "url": "http://httpbin.org/post"
}
```
![POST](https://qiita-image-store.s3.amazonaws.com/0/32453/a0499631-0a60-2d0b-dc31-a6e4e6d52a00.png)


curlだと

```bash
$ curl -i -X POST http://httpbin.org/post \
  --header "Content-type: application/json" \
  --header 'X-Api-Agent: 123' \
  --data '{"name":"John"}'
```

となります。

逆に`HTTPie`で`form`として送りたい場合は、`-f`オプションを使用します。

#### JSONを送る際のTIPS

```bash
http POST http://httpbin.org/post name=John age:=29 married:=false array:='["value1","value2"]'
```

これで`"{\"name\": \"John\", \"age\": 29, \"married\": false, \"array\": [\"value1\", \"value2\"]}"`のdataが送られます。

`=`を使用すると`name=John`が`"name": "John"`として
標準で右辺は`String`ですが、`:=`を使用すると`int`や`bool`も送れます。
配列を送りたい場合は、`'["value1","value2"]'`のようにします。
ファイルから読み込む場合は`=@`か`:=@`を使用します。

詳しくはドキュメントを参照してください。
[Documentation | HTTPie – CLI HTTP client](https://httpie.org/doc#json)

#### Windowsで使う場合の注意点

`"`が特殊文字として扱われるため、コマンドラインでは正しく動作しません。PowerShellを使って、`"`を`\"`としてエスケープすれば同じように動作します。

シェル、PowerShellからかるーい感じでHTTPアクセスしたい方は使ってみてはいかがでしょうか？

以上です。