
それゆけ!ターミナル部 第12回
Web開発に便利なツールを使ってみよう!
みなさんこんにちは!ターミナル部部長のタナカトモフミです。
本連載では意外と見落としがちな基本的な事柄からちょっとマニアックなテクニックまで、ターミナルを使いこなすための方法を若手エンジニアのタミ夫くんとシェルスキー先生と一緒に学んでいきます。
最終回となる今回はWeb開発に便利なツールとして「httpie」を紹介します。httpieはターミナルで使用できるHTTPクライアントツールです。ターミナルで使用するHTTPクライアントの定番といえば、wgetやcurlですが、httpieはわかりやすいオプションやJSONのリクエストボディを簡単に送れる、レスポンスボディのシンタックスハイライトなど多機能で使いやすいツールです。活用することでWebアプリケーションのテストや開発時の動作確認などを効率的に行うことができます。
ターミナルでの作業はいつもは先生に教わってばかりのタミ夫くんですが、今日は一人ドヤ顔で作業をしています。
-
お、何やらちょっとターミナルで開発作業をしているようじゃな。
-
いやーこれ便利だわー。こうやって使えばいいのかなるほどねー。
-
どうしたんじゃ?
-
最近ターミナル上でのツールいろいろ見つけて試してるんスよ。
-
それは良いことじゃな。自分の効率を上げるためには、日々研鑽は必要じゃ。
-
せっかくなんで、今日は俺がhttpieってツールを教えてあげますよ。なんせ師匠は21世紀なのに、ちゃんとWeb開発とかやったことないって話なんで!
-
ぐぬぬ。(調子に乗っておる。。。)
httpie で Web開発もターミナルからやってみよう!
なにはともあれまずはhttpieをインストールしましょう。いつも通りhomebrewで簡単にインストールすることができます。
$ brew install httpie $ http --version 0.9.8
パッケージの名前は、「httpie」ですが、コマンドの名前は「http」になる点に注意してください。まずは、httpieの便利を体験するためにJSONのレスポンスボディを表示するリクエストを送ってみましょう。今回は、「httpbin.org」を使用してテストしてみます。
$ http http://httpbin.org/user-agent HTTP/1.1 200 OK Access-Control-Allow-Credentials: true Access-Control-Allow-Origin: * Connection: keep-alive Content-Length: 35 Content-Type: application/json Date: Sun, 19 Feb 2017 15:20:03 GMT Server: nginx { "user-agent": "HTTPie/0.9.8" }

画像を比較するとわかるように、curlでは、「-i」オプションを指定しないと出なかったレスポンスヘッダーがデフォルトで表示されていたり、ヘッダーのキーとバリューそれぞれに色がつくことでわかりやすい表示になっています。さらに、レスポンスボディのJSONもハイライトされて綺麗な表示になっています。
このように単純なリクエストの送信もcurlよりもわかりやすく開発に便利に使えることがわかります。
以降ではさらに便利な開発者向けのhttpieの使い方を紹介していきます。
リクエストボディの送り方
httpieでは当然のことながらGETだけでなくPOSTやPUTといったリクエストを送ることもできます。その際、フォームやJSON形式のリクエストボディを簡単に送信することができるようになっています。
基本的な使い方は以下の通りです。
$ http オプション メソッド名 URL リクエストボディ
例としてPOSTでJSONを送信してみましょう。「--verbose」オプション(「-v」でも同じ)はリクエストヘッダ・ボディを表示することができるオプションです。ボディをkey1=value1 key2=value2 と指定すると自動的に{ "key1": "value1", "key2": "value2"} のJSONへと変換されるのがポイントです。
$ http --verbose POST http://httpbin.org/post key1=value1 key2=value2 POST /post HTTP/1.1 Accept: application/json, */* Accept-Encoding: gzip, deflate Connection: keep-alive Content-Length: 36 Content-Type: application/json Host: httpbin.org User-Agent: HTTPie/0.9.8 { "key1": "value1", "key2": "value2" } HTTP/1.1 200 OK Access-Control-Allow-Credentials: true Access-Control-Allow-Origin: * Connection: keep-alive Content-Length: 468 Content-Type: application/json Date: Sun, 19 Feb 2017 16:16:54 GMT Server: nginx { "args": {}, "data": "{\"key1\": \"value1\", \"key2\": \"value2\"}", "files": {}, "form": {}, "headers": { "Accept": "application/json, */*", "Accept-Encoding": "gzip, deflate", "Content-Length": "36", "Content-Type": "application/json", "Host": "httpbin.org", "User-Agent": "HTTPie/0.9.8" }, "json": { "key1": "value1", "key2": "value2" }, "origin": "x.x.x.x", "url": "http://httpbin.org/post" }
このようにデフォルトでは、リクエストボディはJSON形式で送信されます。フォーム形式(application/x-www-form-urlencoded)でリクエストボディを送りたい場合は「--form」オプション(「-f」でも同じ)を使用します。
$ http --verbose --form PUT http://httpbin.org/put key1=value1 key2=value2 PUT /put HTTP/1.1 Accept: */* Accept-Encoding: gzip, deflate Connection: keep-alive Content-Length: 23 Content-Type: application/x-www-form-urlencoded; charset=utf-8 Host: httpbin.org User-Agent: HTTPie/0.9.8 key1=value1&key2=value2 HTTP/1.1 200 OK Access-Control-Allow-Credentials: true Access-Control-Allow-Origin: * Connection: keep-alive Content-Length: 439 Content-Type: application/json Date: Sun, 19 Feb 2017 16:23:29 GMT Server: nginx { "args": {}, "data": "", "files": {}, "form": { "key1": "value1", "key2": "value2" }, "headers": { "Accept": "*/*", "Accept-Encoding": "gzip, deflate", "Content-Length": "23", "Content-Type": "application/x-www-form-urlencoded; charset=utf-8", "Host": "httpbin.org", "User-Agent": "HTTPie/0.9.8" }, "json": null, "origin": "x.x.x.x", "url": "http://httpbin.org/put" }
非常に簡単にJSON・フォームのリクエストを送ることができました。続いては、ログインセッション(Cookie)を扱う方法を紹介します。
セッションを扱う
Webでは、ユーザを判別するセッション情報をCookieにセットすることが多いと思います。開発時には、テスト用ユーザを切り替えて、リクエストを送ることも多いでしょう。httpieでは、そのような場合のために、「--session」オプションを指定して、Cookieの保存と送信を簡単に切り替えることができます。以下、「--session」オプションの使用例を示します。
1) user1セッションの現在のCookieを表示する。現在は空。
$ http --verbose --session user1 http://httpbin.org/cookies GET /cookies HTTP/1.1 Accept: */* Accept-Encoding: gzip, deflate Connection: keep-alive Host: httpbin.org User-Agent: HTTPie/0.9.8 HTTP/1.1 200 OK Access-Control-Allow-Credentials: true Access-Control-Allow-Origin: * Connection: keep-alive Content-Length: 20 Content-Type: application/json Date: Sun, 19 Feb 2017 16:45:37 GMT Server: nginx { "cookies": {} }
2) user1セッションのCookieに値をセットする。
$ http --verbose --session user1 http://httpbin.org/cookies/set?key1=value1 GET /cookies/set?key1=value1 HTTP/1.1 Accept: */* Accept-Encoding: gzip, deflate Connection: keep-alive Host: httpbin.org User-Agent: HTTPie/0.9.8 HTTP/1.1 302 FOUND Access-Control-Allow-Credentials: true Access-Control-Allow-Origin: * Connection: keep-alive Content-Length: 223 Content-Type: text/html; charset=utf-8 Date: Sun, 19 Feb 2017 16:45:46 GMT Location: /cookies Server: nginx Set-Cookie: key1=value1; Path=/ <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> <title>Redirecting...</title> <h1>Redirecting...</h1> <p>You should be redirected automatically to target URL: <a href="/cookies">/cookies</a>. If not click the link.
3) user1セッションの現在のCookieを表示する。key1がセットされている。
$ http --verbose --session user1 http://httpbin.org/cookies GET /cookies HTTP/1.1 Accept: */* Accept-Encoding: gzip, deflate Connection: keep-alive Cookie: key1=value1 Host: httpbin.org User-Agent: HTTPie/0.9.8 HTTP/1.1 200 OK Access-Control-Allow-Credentials: true Access-Control-Allow-Origin: * Connection: keep-alive Content-Length: 44 Content-Type: application/json Date: Sun, 19 Feb 2017 16:45:55 GMT Server: nginx { "cookies": { "key1": "value1" } }
4) user2セッションの現在のCookieを表示する。セッションが違うので空。
$ http --verbose --session user2 http://httpbin.org/cookies GET /cookies HTTP/1.1 Accept: */* Accept-Encoding: gzip, deflate Connection: keep-alive Host: httpbin.org User-Agent: HTTPie/0.9.8 HTTP/1.1 200 OK Access-Control-Allow-Credentials: true Access-Control-Allow-Origin: * Connection: keep-alive Content-Length: 20 Content-Type: application/json Date: Sun, 19 Feb 2017 16:51:45 GMT Server: nginx { "cookies": {} }
このように簡単にCookieを切り替えることができるので、ログイン用のフォームへログインリクエストを送ってセッションごとに保存しておけば、ユーザを切り替えながらフォームやAPIのテストが簡単にできるようになります。
その他いろいろな機能を使ってみよう!
URLの指定では、「http://」を省略することができます。これだけでもタイプする量が減って嬉しい機能です。
URLの省略指定
URLの指定では、「http://」を省略することができます。これだけでもタイプする量が減って嬉しい機能です。
$ http httpbin.org/user-agent
デフォルトでは、「http」でアクセスしますが、デフォルトで「https」を使用して欲しい場合は、以下のエイリアスを用意しておきましょう。
$ alias https='http --default-scheme=https'
また、開発時には「localhost:port」を指定することが非常に多いと思います。そこでhttpieでは、この定型句をさらに省略できるようにしており、パスから指定するだけでローカルホストにアクセスしてくれます。
# http://localhost/users へのアクセスを /users だけに省略できる $ http /users # ポート番号の指定をする場合 (http://localhost:9000/users) $ http :9000/users
開発時にはタイプ数が圧倒的に減るので、非常に楽になります。ぜひ覚えておきましょう。
HTTPヘッダーの指定
URLの後ろに「:」でつないだ「ヘッダー名:値」という形式で指定すれば、リクエストボディではなくヘッダーとして送信されます。
$ http -v http://httpbin.org/user-agent X-Hello-Header:100 GET /user-agent HTTP/1.1 Accept: */* Accept-Encoding: gzip, deflate Connection: keep-alive Host: httpbin.org User-Agent: HTTPie/0.9.8 X-Hello-Header: 100
クエリーストリングの指定
URLの後ろに「パラメータ名==値」という形式でパラメータを指定するとクエリーストリングとして送信されます。
$ http -v www.google.com search=='HTTPie logo' tbm==isch GET /?search=HTTPie+logo&tbm=isch HTTP/1.1 Accept: */* Accept-Encoding: gzip, deflate Connection: keep-alive Host: www.google.com User-Agent: HTTPie/0.9.8
通常クエリをターミナルで指定しようとすると「&」の文字がシェルに解釈されるため、URLをシングルクォートで囲む必要があり面倒なのですが、httpieを使えばこういった面倒がありません。また、自動的にエスケープ処理をしてくれますので特殊な文字を送りたい場合も問題なく送信できます。
ファイルの送信
ファイルの中身をリクエストボディとして送ることができます。
$ cat hello.json { "key1": "value1", "key2": "value2" } $ http -v POST httpbin.org/post < hello.json POST /post HTTP/1.1 Accept: application/json, */* Accept-Encoding: gzip, deflate Connection: keep-alive Content-Length: 47 Content-Type: application/json Host: httpbin.org User-Agent: HTTPie/0.9.8 { "key1": "value1", "key2": "value2" } ...
非常に簡単です。その他にもファイルをアップロードするような処理のため、「multipart/form-data」の送信にも対応しています。
例えば以下のようなファイルのアップロードフォームがある場合
<form enctype="multipart/form-data" method="post" action="/post"> <input type="text" name="name" /> <input type="file" name="resume" /> </form>
以下のオプション指定をすれば、ファイル送信に対応したリクエストを送信することができます。
# @を使ってファイルのパスを指定することで送信が可能になる $ http -v --form POST httpbin.org/post name=John resume@./resume.txt POST /post HTTP/1.1 Accept: */* Accept-Encoding: gzip, deflate Connection: keep-alive Content-Length: 269 Content-Type: multipart/form-data; boundary=de750975ab8149df9e7b44a52fa57217 Host: httpbin.org User-Agent: HTTPie/0.9.8 --de750975ab8149df9e7b44a52fa57217 Content-Disposition: form-data; name="name" John --de750975ab8149df9e7b44a52fa57217 Content-Disposition: form-data; name="resume"; filename="resume.txt" Content-Type: text/plain John --de750975ab8149df9e7b44a52fa57217-- ...
ファイルのダウンロード
送信だけでなくダウンロードも簡単に扱うことができます。通常のダウンロードは「>」でリダイレクトするだけでファイル保存ができます。
$ http httpbin.org/image/png > png.png
ファイル名を指定せずともwgetのようによしなにダウンロードして欲しい場合は、「--download」オプションを使用することもできます。「--download」オプションを使えば、あとどれくらい時間がかかりそうか?といった進捗情報も表示され見やすくなります。
$ http --download https://github.com/gitbucket/gitbucket/releases/download/4.9/gitbucket.war HTTP/1.1 200 OK Accept-Ranges: bytes Content-Disposition: attachment; filename=gitbucket.war Content-Length: 48067428 Content-Type: application/octet-stream Date: Mon, 20 Feb 2017 01:57:01 GMT ETag: "2173d2cd45498c26a6fe198016158a24" Last-Modified: Sat, 28 Jan 2017 17:10:48 GMT Server: AmazonS3 x-amz-id-2: s6DIwYYplxLgQy5vKNFSps4x0kGnm2/+m+RiNT4lcWy/Q9mhOm7GSzJWfmAoKf0Jx7uxE9kvtFU= x-amz-request-id: D7C2F760BA369AA4 Downloading 45.84 MB to "gitbucket.war" Done. 45.84 MB in 24.10532s (1.90 MB/s)
JSONのパラメータの指定方法
冒頭で「key=value」の形式でJSONのボディを送れると紹介しましたが、これでは実際のJSONを作るには不十分です。例えば、BooleanやNumberのような型の値を送りたい場合でも、文字列として送られてしまいます。
大きなサイズの場合はファイル指定での送信をオススメしますが、ちょっとしたJSONを送りたい場合、「=」ではなく、「:=」を使用することでBooleanやNumberなどの型の値を送ることができます。
$ http -v POST httpbin.org/post key1=true key2:=true key3:=[1,2,3] POST /post HTTP/1.1 Accept: application/json, */* Accept-Encoding: gzip, deflate Connection: keep-alive Content-Length: 30 Content-Type: application/json Host: httpbin.org User-Agent: HTTPie/0.9.8 { "key1": "true", # ダブルクォートで囲まれた文字列として送信されている "key2": true, # ダブルクォートなしになっておりBoolean型で送信されている "key3": [ # Arrayで送信されている 1, 2, 3 ] }
httpieにはこの他にも様々な機能がありますので公式サイト(https://github.com/jkbrzt/httpie)の使い方に一通り目を通しておくとよいでしょう。
まとめ
-
いやぁ成長したのう。自ら探すこともできるようになっておるのう。
-
いやいやこれぐらいは誰でもやってるっスわ。
-
ではそろそろお告げの時かのう。
-
お?もしかして俺、表彰されちゃう感じっスか?
-
いや、ワシの引退が決まったんじゃ。
-
引退って何からっスか?
-
エンジニアじゃ。ワシは定年を迎えたんじゃ。これからは田舎でトマト栽培をするんじゃよ。
-
マジっスか。あれすか35歳定年的なやつっスか?
-
それだと君が生まれる前に定年迎えておるのう…。ワシはもう70歳じゃ。
-
えー!老けてるとは思ってましたけど、ぱねぇっスねー。おつかれした!
-
お、おう。(ターミナル部どうしようかのう・・・)
引退の日...
-
師匠お世話になりました。これ菓子折りっス。甘いもの食べれない年頃だと思うんで、硬めのせんべいにしときました。アゴは鍛えた方がいいっスよー。
-
お、おう、ありがとう。心機一転でお互いがんばろうな。
-
もちっス。ターミナル部は引き継いで新入社員たちに布教するんで、安心してナス育ててください!
-
お、おう(いや、トマトだよ。)。それは嬉しいのう。あとは任せたぞ。
-
うす!(やべー半分くらい覚えてないけど、半分くらいは教えてあげよっと。)
時代は変わってもソフトウェアの開発・運用にターミナルでの作業は欠かせません。シェルスキー先生は定年退職してしまいますが、これからはタミ夫くんによってターミナルでの作業テクニックは連綿と受け継がれていくことでしょう。読者の皆さんも是非本連載で紹介したツールやテクニックを活用して快適なターミナルライフを送っていただくとともに、ターミナル部の一員として次世代への伝承や新たなツールの探求にも励んでいただくことを期待して連載を終わりたいと思います。半年間お付き合いいただきありがとうございました。
完