🔥
httpie 使い方メモ
ついついcurl使いがちなんだけど、httpieに移行していきたいと思ったので使い方メモ
Install
brew install httpie
Help
helpとかmanを眺めるのって大事だよね
$ http --help
usage: http [--json] [--form] [--multipart] [--boundary BOUNDARY] [--raw RAW] [--compress]
[--pretty {all,colors,format,none}] [--style STYLE] [--unsorted] [--sorted]
[--response-charset ENCODING] [--response-mime MIME_TYPE] [--format-options FORMAT_OPTIONS]
[--print WHAT] [--headers] [--body] [--verbose] [--all] [--history-print WHAT] [--stream]
[--output FILE] [--download] [--continue] [--quiet]
[--session SESSION_NAME_OR_PATH | --session-read-only SESSION_NAME_OR_PATH]
[--auth USER[:PASS]] [--auth-type {basic,digest}] [--ignore-netrc] [--offline]
[--proxy PROTOCOL:PROXY_URL] [--follow] [--max-redirects MAX_REDIRECTS]
[--max-headers MAX_HEADERS] [--timeout SECONDS] [--check-status] [--path-as-is] [--chunked]
[--verify VERIFY] [--ssl {ssl2.3,tls1,tls1.1,tls1.2}] [--ciphers CIPHERS] [--cert CERT]
[--cert-key CERT_KEY] [--ignore-stdin] [--help] [--version] [--traceback]
[--default-scheme DEFAULT_SCHEME] [--debug]
[METHOD] URL [REQUEST_ITEM ...]
Usage
普通にGET取得する
$ http GET https://mattak.netlify.app
HTTP/1.1 200 OK
age: 1
cache-control: public, max-age=0, must-revalidate
content-encoding: gzip
content-type: text/html; charset=UTF-8
date: Tue, 14 Dec 2021 13:58:19 GMT
etag: "7bb91bbc5f12f51ab5a7d047d15173e0-ssl-df"
server: Netlify
strict-transport-security: max-age=31536000; includeSubDomains; preload
transfer-encoding: chunked
vary: Accept-Encoding
x-nf-request-id: 01FPWKS8HYSCG8TAWT499DC8W1
<!DOCTYPE html><html><head>
...
リダイレクトつけるとheaderは無くしつつcontentだけ出力してくれるっぽい (親切)
$ http GET https://mattak.netlify.app > /tmp/index.html
$ open /tmp/index.html # そのまま開ける
jqでそのままつなげる
$ http GET https://api.github.com/users/defunkt | jq .
{
"avatar_url": "https://avatars.githubusercontent.com/u/2?v=4",
"bio": "🍔",
"blog": "http://chriswanstrath.com/",
"company": null,
"created_at": "2007-10-20T05:24:19Z",
"email": null,
"events_url": "https://api.github.com/users/defunkt/events{/privacy}",
"followers": 21322,
"followers_url": "https://api.github.com/users/defunkt/followers",
"following": 210,
"following_url": "https://api.github.com/users/defunkt/following{/other_user}",
"gists_url": "https://api.github.com/users/defunkt/gists{/gist_id}",
"gravatar_id": "",
"hireable": null,
"html_url": "https://github.com/defunkt",
"id": 2,
"location": null,
"login": "defunkt",
"name": "Chris Wanstrath",
"node_id": "MDQ6VXNlcjI=",
"organizations_url": "https://api.github.com/users/defunkt/orgs",
"public_gists": 273,
"public_repos": 107,
"received_events_url": "https://api.github.com/users/defunkt/received_events",
"repos_url": "https://api.github.com/users/defunkt/repos",
"site_admin": false,
"starred_url": "https://api.github.com/users/defunkt/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/defunkt/subscriptions",
"twitter_username": null,
"type": "User",
"updated_at": "2021-07-29T11:10:23Z",
"url": "https://api.github.com/users/defunkt"
}
GETとかPOSTは省略可能みたい.
$ http pie.dev/post hello=offline
HTTP/1.1 200 OK
CF-Cache-Status: DYNAMIC
CF-RAY: 6bd800091c8834e7-NRT
Connection: keep-alive
Content-Encoding: gzip
Content-Type: application/json
Date: Tue, 14 Dec 2021 14:07:43 GMT
NEL: {"success_fraction":0,"report_to":"cf-nel","max_age":604800}
Report-To: {"endpoints":[{"url":"https:\/\/a.nel.cloudflare.com\/report\/v3?s=4JWbRqN8jnftB1yNrKSifkrZ0FKYMI4Jqgs%2BsbWQGpcv4scuKBsP6xVFvKJRVmUocJEbPqy4BVf1Vo%2FQ4Mu2xDKHkFggRbOoio5Ze3GjI21rnbDYFVlNWz7ApPSYMkjew94I1kK9"}],"group":"cf-nel","max_age":604800}
Server: cloudflare
Transfer-Encoding: chunked
access-control-allow-credentials: true
access-control-allow-origin: *
alt-svc: h3=":443"; ma=86400, h3-29=":443"; ma=86400, h3-28=":443"; ma=86400, h3-27=":443"; ma=86400
{
"args": {},
"data": "{\"hello\": \"offline\"}",
"files": {},
"form": {},
"headers": {
"Accept": "application/json, */*;q=0.5",
"Accept-Encoding": "gzip",
"Cdn-Loop": "cloudflare",
"Cf-Connecting-Ip": "240d:1a:cc8:ca00:914:bfe3:c96c:bb67",
"Cf-Ipcountry": "JP",
"Cf-Ray": "6bd800091c8834e7-FRA",
"Cf-Visitor": "{\"scheme\":\"http\"}",
"Connection": "Keep-Alive",
"Content-Length": "20",
"Content-Type": "application/json",
"Host": "pie.dev",
"User-Agent": "HTTPie/2.6.0"
},
"json": {
"hello": "offline"
},
"origin": "240d:1a:cc8:ca00:914:bfe3:c96c:bb67",
"url": "http://pie.dev/post"
}
-v
でRequestHeaderも見れるようだ.
defaultでapplication/jsonのpostになってるのは便利!
$ http -v pie.dev/post hello=offline ~/github/mattak/blog [master|mattak|largeforest.local|23:07:43]
POST /post HTTP/1.1
Accept: application/json, */*;q=0.5
Accept-Encoding: gzip, deflate
Connection: keep-alive
Content-Length: 20
Content-Type: application/json
Host: pie.dev
User-Agent: HTTPie/2.6.0
{
"hello": "offline"
}
HTTP/1.1 200 OK
CF-Cache-Status: DYNAMIC
CF-RAY: 6bd8010ff91a80d5-NRT
Connection: keep-alive
Content-Encoding: gzip
Content-Type: application/json
Date: Tue, 14 Dec 2021 14:08:25 GMT
NEL: {"success_fraction":0,"report_to":"cf-nel","max_age":604800}
Report-To: {"endpoints":[{"url":"https:\/\/a.nel.cloudflare.com\/report\/v3?s=QhcVNP02aLK8MKFz08X33FL%2B63UBGHv71rwfbLfbp%2BQdD47n6AVJA4oL28xMnWZqI2Nagfg9VoK%2BXQh2htSCVz98n6MG3Q0BIZXpjADe53zxE6uu4pXEGxG%2FCivhHTLCELcyjb%2F4"}],"group":"cf-nel","max_age":604800}
Server: cloudflare
Transfer-Encoding: chunked
access-control-allow-credentials: true
access-control-allow-origin: *
alt-svc: h3=":443"; ma=86400, h3-29=":443"; ma=86400, h3-28=":443"; ma=86400, h3-27=":443"; ma=86400
{
"args": {},
"data": "{\"hello\": \"offline\"}",
"files": {},
"form": {},
"headers": {
"Accept": "application/json, */*;q=0.5",
"Accept-Encoding": "gzip",
"Cdn-Loop": "cloudflare",
"Cf-Connecting-Ip": "240d:1a:cc8:ca00:914:bfe3:c96c:bb67",
"Cf-Ipcountry": "JP",
"Cf-Ray": "6bd8010ff91a80d5-FRA",
"Cf-Visitor": "{\"scheme\":\"http\"}",
"Connection": "Keep-Alive",
"Content-Length": "20",
"Content-Type": "application/json",
"Host": "pie.dev",
"User-Agent": "HTTPie/2.6.0"
},
"json": {
"hello": "offline"
},
"origin": "240d:1a:cc8:ca00:914:bfe3:c96c:bb67",
"url": "http://pie.dev/post"
}
入力パイプからbody取れるのは地味にいいよね
$ http -v pie.dev/post < /tmp/post.json
POST /post HTTP/1.1
Accept: application/json, */*;q=0.5
Accept-Encoding: gzip, deflate
Connection: keep-alive
Content-Length: 27
Content-Type: application/json
Host: pie.dev
User-Agent: HTTPie/2.6.0
{
"hello": "offline"
}
HTTP/1.1 200 OK
CF-Cache-Status: DYNAMIC
CF-RAY: 6bd8038d8acbf8bb-NRT
Connection: keep-alive
Content-Encoding: gzip
Content-Type: application/json
Date: Tue, 14 Dec 2021 14:10:07 GMT
NEL: {"success_fraction":0,"report_to":"cf-nel","max_age":604800}
Report-To: {"endpoints":[{"url":"https:\/\/a.nel.cloudflare.com\/report\/v3?s=ZiU0fLeDa%2FwaQAgWM9sJ4LfQwr%2Bg63zflgIT8EfLv9uICrgcJH7Wq%2Bf39bpFOEXyFI%2B%2FYsQ8XuMdyuIMdF%2BXkfuA0rr3f8WP%2B28qKuXRpAMEAMISA5%2BKWX0PVvTADDpl8b%2FMFaNd"}],"group":"cf-nel","max_age":604800}
Server: cloudflare
Transfer-Encoding: chunked
access-control-allow-credentials: true
access-control-allow-origin: *
alt-svc: h3=":443"; ma=86400, h3-29=":443"; ma=86400, h3-28=":443"; ma=86400, h3-27=":443"; ma=86400
{
"args": {},
"data": "{\n \"hello\": \"offline\"\n}\n",
"files": {},
"form": {},
"headers": {
"Accept": "application/json, */*;q=0.5",
"Accept-Encoding": "gzip",
"Cdn-Loop": "cloudflare",
"Cf-Connecting-Ip": "240d:1a:cc8:ca00:914:bfe3:c96c:bb67",
"Cf-Ipcountry": "JP",
"Cf-Ray": "6bd8038d8acbf8bb-FRA",
"Cf-Visitor": "{\"scheme\":\"http\"}",
"Connection": "Keep-Alive",
"Content-Length": "27",
"Content-Type": "application/json",
"Host": "pie.dev",
"User-Agent": "HTTPie/2.6.0"
},
"json": {
"hello": "offline"
},
"origin": "240d:1a:cc8:ca00:914:bfe3:c96c:bb67",
"url": "http://pie.dev/post"
}
X-Sample-Versionっていうヘッダも適当につけてみた.
:
と =
でよしなに解釈してくれるのは結構楽でいい!
$ http -v pie.dev/post hello=offline X-Sample-Version:1
POST /post HTTP/1.1
Accept: application/json, */*;q=0.5
Accept-Encoding: gzip, deflate
Connection: keep-alive
Content-Length: 20
Content-Type: application/json
Host: pie.dev
User-Agent: HTTPie/2.6.0
X-Sample-Version: 1
{
"hello": "offline"
}
...
感想
curlは細かい操作がなんでもできるけど、記述が冗長で現代のusageにfitしてない.
httpieはよくやる操作がシンプルで心地いいI/Fだと感じた.
普段使いはこれからhttpieにしていこう
Discussion