はじめに
業務でcurlコマンドを使用する必要があるため、その学習メモになります。
実際にコマンドを叩きながらまとめましたので、同じような境遇の方の参考になれば幸いです。
curlとは
正式名称:cURL (Client for URL)
cURL (client for URL)とは、 Linux などの UNIX系OS でよく利用される コマンドラインツール の一つで、 URL で示される ネットワーク 上の場所に対して様々な プロトコル (通信手順)を用いて アクセス できるもの。 MITライセンス に基づき オープンソースソフトウェア として公開されている。
HTTPやFTPなどのプロトコルを使用して、サーバに対してデータの送受信を行うコマンドということがわかります。
curlの使用用途としては、APIを叩いたり、サーバに対してリクエストを行いレスポンスを確認することが多いです。
準備
macOSで実行していきます。
version確認
curlコマンドがインストールされているか確認できます。
curl --version
バージョンが確認できれば準備完了です。
curl 8.7.1 (x86_64-apple-darwin22.0) libcurl/8.7.1 (SecureTransport) LibreSSL/3.3.6 zlib/1.2.11 nghttp2/1.51.0
Release-Date: 2024-03-27
Protocols: dict file ftp ftps gopher gophers http https imap imaps ipfs ipns ldap ldaps mqtt pop3 pop3s rtsp smb smbs smtp smtps telnet tftp
Features: alt-svc AsynchDNS GSS-API HSTS HTTP2 HTTPS-proxy IPv6 Kerberos Largefile libz MultiSSL NTLM SPNEGO SSL threadsafe UnixSockets
今回の記事では以下のサイトを使用してGET・POSTを試します。
https://httpbin.org/
上記サイトのURLに対してリクエストを行うと、レスポンスを返してくれます。
自分でAPIサーバを作る必要がないので、コマンドを試す際に便利です。
構文とオプション
基本構文
curl [オプション] [URL]
改行したい場合は以下のように\
を入れます。
curl -X GET \
> -I 'https://httpbin.org/get'
-X
:HTTPリクエストの指定
GET
# デフォルトがGETなので、-Xをつけなくてもいい
curl 'https://httpbin.org/get'
curl -X GET 'https://httpbin.org/get'
レスポンス
{
"args": {},
"headers": {
"Accept": "*/*",
"Host": "httpbin.org",
"User-Agent": "curl/8.7.1",
"X-Amzn-Trace-Id": "Root=1-67c90df3-6d2591cb23f7596d5d7dcffe"
},
"origin": "***.***.***.***",
"url": "https://httpbin.org/get"
}
POST
curl -X POST 'https://httpbin.org/post'
レスポンス
{
"args": {},
"data": "",
"files": {},
"form": {},
"headers": {
"Accept": "*/*",
"Host": "httpbin.org",
"User-Agent": "curl/8.7.1",
"X-Amzn-Trace-Id": "Root=1-67c90ce4-42e4398a0e790f263dbeb372"
},
"json": null,
"origin": "***.***.***.***",
"url": "https://httpbin.org/post"
}
-H
:ヘッダーの追加
GET
curl -H "content-type: application/json" 'https://httpbin.org/get'
レスポンス
{
"args": {},
"headers": {
"Accept": "*/*",
"Content-Type": "application/json",
"Host": "httpbin.org",
"User-Agent": "curl/8.7.1",
"X-Amzn-Trace-Id": "Root=1-67c94239-6725112e266c77be1904a9f8"
},
"origin": "***.***.***.***",
"url": "https://httpbin.org/get"
}
POST
curl -X POST -H "content-type: application/json" 'https://httpbin.org/post'
レスポンス
# レスポンス
{
"args": {},
"headers": {
"Accept": "*/*",
"Content-Type": "application/json",
"Host": "httpbin.org",
"User-Agent": "curl/8.7.1",
"X-Amzn-Trace-Id": "Root=1-67c94239-6725112e266c77be1904a9f8"
},
"origin": "***.***.***.***",
"url": "https://httpbin.org/get"
}
-d
:データの送信
POST
curl -X POST \
> -H "content-type: application/json" \
> -d '{"first_name":"Tarou","last_name":"Yamada","age":"20"}' \
> 'https://httpbin.org/post'
ver7.82.0以降なら以下のように--json
で-H
と-d
を使用せずにjsonデータを送信できるようです。-X
もいらないのでかなりスッキリして見やすいです。
今回は昔からある上記のコマンドで試していきます。
curl --json '{"first_name":"Tarou","last_name":"Yamada","age":"20"}' \
> 'https://httpbin.org/post'
レスポンス
{
"args": {},
"data": "{\"first_name\":\"Tarou\",\"last_name\":\"Yamada\",\"age\":\"20\"}",
"files": {},
"form": {},
"headers": {
"Accept": "*/*",
"Content-Length": "54",
"Content-Type": "application/json",
"Host": "httpbin.org",
"User-Agent": "curl/8.7.1",
"X-Amzn-Trace-Id": "Root=1-67c944bc-33471697605a48e957157a5c"
},
"json": {
"age": "20",
"first_name": "Tarou",
"last_name": "Yamada"
},
"origin": "***.***.***.***",
"url": "https://httpbin.org/post"
}
-I
:レスポンスヘッダーのみを出力
GET
curl -I 'https://httpbin.org/get'
レスポンス
HTTP/2 200
date: Thu, 06 Mar 2025 06:48:50 GMT
content-type: application/json
content-length: 254
server: gunicorn/19.9.0
access-control-allow-origin: *
access-control-allow-credentials: true
POST
curl -X POST -I 'https://httpbin.org/post'
レスポンス
HTTP/2 200
date: Thu, 06 Mar 2025 06:51:45 GMT
content-type: application/json
content-length: 318
server: gunicorn/19.9.0
access-control-allow-origin: *
access-control-allow-credentials: true
-i
:レスポンスヘッダー・ボディーを出力
GET
curl -i 'https://httpbin.org/get'
レスポンス
HTTP/2 200
date: Thu, 06 Mar 2025 06:53:35 GMT
content-type: application/json
content-length: 254
server: gunicorn/19.9.0
access-control-allow-origin: *
access-control-allow-credentials: true
{
"args": {},
"headers": {
"Accept": "*/*",
"Host": "httpbin.org",
"User-Agent": "curl/8.7.1",
"X-Amzn-Trace-Id": "Root=1-67c9466f-1a0dd9443a036c5e472e9fbe"
},
"origin": "***.***.***.***",
"url": "https://httpbin.org/get"
}
POST
curl -X POST \
> -H "content-type: application.json" \
> -d '{"first_name":"Tarou","last_name":"Yamada","age":"20"}' \
> -i 'https://httpbin.org/post'
レスポンス
HTTP/2 200
date: Thu, 06 Mar 2025 07:10:58 GMT
content-type: application/json
content-length: 527
server: gunicorn/19.9.0
access-control-allow-origin: *
access-control-allow-credentials: true
{
"args": {},
"data": "{\"first_name\":\"Tarou\",\"last_name\":\"Yamada\",\"age\":\"20\"}",
"files": {},
"form": {},
"headers": {
"Accept": "*/*",
"Content-Length": "54",
"Content-Type": "application.json",
"Host": "httpbin.org",
"User-Agent": "curl/8.7.1",
"X-Amzn-Trace-Id": "Root=1-67c94a82-42f3c8850c0b5edb7ce8a7b3"
},
"json": {
"age": "20",
"first_name": "Tarou",
"last_name": "Yamada"
},
"origin": "***.***.***.***",
"url": "https://httpbin.org/post"
}
-v
:HTTP通信の詳細を出力
GET
curl -v 'https://httpbin.org/get'
レスポンス
* Host httpbin.org:443 was resolved.
* IPv6: (none)
* IPv4: 44.205.219.248, 44.196.147.43, 54.144.47.213, 34.205.201.49
* Trying 44.205.219.248:443...
* Connected to httpbin.org (44.205.219.248) port 443
* ALPN: curl offers h2,http/1.1
* (304) (OUT), TLS handshake, Client hello (1):
* CAfile: /etc/ssl/cert.pem
* CApath: none
* (304) (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
* TLSv1.2 (IN), TLS handshake, Server finished (14):
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
* TLSv1.2 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.2 (OUT), TLS handshake, Finished (20):
* TLSv1.2 (IN), TLS change cipher, Change cipher spec (1):
* TLSv1.2 (IN), TLS handshake, Finished (20):
* SSL connection using TLSv1.2 / ECDHE-RSA-AES128-GCM-SHA256 / [blank] / UNDEF
* ALPN: server accepted h2
* Server certificate:
* subject: CN=httpbin.org
* start date: Aug 20 00:00:00 2024 GMT
* expire date: Sep 17 23:59:59 2025 GMT
* subjectAltName: host "httpbin.org" matched cert's "httpbin.org"
* issuer: C=US; O=Amazon; CN=Amazon RSA 2048 M02
* SSL certificate verify ok.
* using HTTP/2
* [HTTP/2] [1] OPENED stream for https://httpbin.org/get
* [HTTP/2] [1] [:method: GET]
* [HTTP/2] [1] [:scheme: https]
* [HTTP/2] [1] [:authority: httpbin.org]
* [HTTP/2] [1] [:path: /get]
* [HTTP/2] [1] [user-agent: curl/8.7.1]
* [HTTP/2] [1] [accept: */*]
> GET /get HTTP/2
> Host: httpbin.org
> User-Agent: curl/8.7.1
> Accept: */*
>
* Request completely sent off
< HTTP/2 200
< date: Thu, 06 Mar 2025 07:14:09 GMT
< content-type: application/json
< content-length: 254
< server: gunicorn/19.9.0
< access-control-allow-origin: *
< access-control-allow-credentials: true
<
{
"args": {},
"headers": {
"Accept": "*/*",
"Host": "httpbin.org",
"User-Agent": "curl/8.7.1",
"X-Amzn-Trace-Id": "Root=1-67c94b41-65631b3f2d6d993c00a431bc"
},
"origin": "***.***.***.***",
"url": "https://httpbin.org/get"
}
POST
curl -X POST \
-H "content-type: application.json" \
-d '{"first_name":"Tarou","last_name":"Yamada","age":"20"}' \
-v 'https://httpbin.org/post'
レスポンス
* Host httpbin.org:443 was resolved.
* IPv6: (none)
* IPv4: 44.205.219.248, 54.144.47.213, 34.205.201.49, 44.196.147.43
* Trying 44.205.219.248:443...
* Connected to httpbin.org (44.205.219.248) port 443
* ALPN: curl offers h2,http/1.1
* (304) (OUT), TLS handshake, Client hello (1):
* CAfile: /etc/ssl/cert.pem
* CApath: none
* (304) (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
* TLSv1.2 (IN), TLS handshake, Server finished (14):
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
* TLSv1.2 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.2 (OUT), TLS handshake, Finished (20):
* TLSv1.2 (IN), TLS change cipher, Change cipher spec (1):
* TLSv1.2 (IN), TLS handshake, Finished (20):
* SSL connection using TLSv1.2 / ECDHE-RSA-AES128-GCM-SHA256 / [blank] / UNDEF
* ALPN: server accepted h2
* Server certificate:
* subject: CN=httpbin.org
* start date: Aug 20 00:00:00 2024 GMT
* expire date: Sep 17 23:59:59 2025 GMT
* subjectAltName: host "httpbin.org" matched cert's "httpbin.org"
* issuer: C=US; O=Amazon; CN=Amazon RSA 2048 M02
* SSL certificate verify ok.
* using HTTP/2
* [HTTP/2] [1] OPENED stream for https://httpbin.org/post
* [HTTP/2] [1] [:method: POST]
* [HTTP/2] [1] [:scheme: https]
* [HTTP/2] [1] [:authority: httpbin.org]
* [HTTP/2] [1] [:path: /post]
* [HTTP/2] [1] [user-agent: curl/8.7.1]
* [HTTP/2] [1] [accept: */*]
* [HTTP/2] [1] [content-type: application.json]
* [HTTP/2] [1] [content-length: 54]
> POST /post HTTP/2
> Host: httpbin.org
> User-Agent: curl/8.7.1
> Accept: */*
> content-type: application.json
> Content-Length: 54
>
* upload completely sent off: 54 bytes
< HTTP/2 200
< date: Thu, 06 Mar 2025 07:17:56 GMT
< content-type: application/json
< content-length: 527
< server: gunicorn/19.9.0
< access-control-allow-origin: *
< access-control-allow-credentials: true
<
{
"args": {},
"data": "{\"first_name\":\"Tarou\",\"last_name\":\"Yamada\",\"age\":\"20\"}",
"files": {},
"form": {},
"headers": {
"Accept": "*/*",
"Content-Length": "54",
"Content-Type": "application.json",
"Host": "httpbin.org",
"User-Agent": "curl/8.7.1",
"X-Amzn-Trace-Id": "Root=1-67c94c23-11076a6c5a5dea02243fce96"
},
"json": {
"age": "20",
"first_name": "Tarou",
"last_name": "Yamada"
},
"origin": "***.***.***.***",
"url": "https://httpbin.org/post"
}
-o
:指定したファイルに出力
GET
curl -o curltest.txt 'https://httpbin.org/get'
レスポンス
cat curltest.txt # ファイル確認
{
"args": {},
"headers": {
"Accept": "*/*",
"Host": "httpbin.org",
"User-Agent": "curl/8.7.1",
"X-Amzn-Trace-Id": "Root=1-67c94fd3-0fe7cd3e1eb8b21b7342af3a"
},
"origin": "***.***.***.***",
"url": "https://httpbin.org/get"
}
POST
curl -X POST \
-H "content-type: application.json" \
-d '{"first_name":"Tarou","last_name":"Yamada","age":"20"}' \
-o curl_post_test.txt 'https://httpbin.org/post'
レスポンス
cat curl_post_test.txt # ファイル確認
{
"args": {},
"data": "{\"first_name\":\"Tarou\",\"last_name\":\"Yamada\",\"age\":\"20\"}",
"files": {},
"form": {},
"headers": {
"Accept": "application/json",
"Content-Length": "54",
"Content-Type": "application/json",
"Host": "httpbin.org",
"User-Agent": "curl/8.7.1",
"X-Amzn-Trace-Id": "Root=1-67c95240-33b6eb2f1fe2ad677c58d801"
},
"json": {
"age": "20",
"first_name": "Tarou",
"last_name": "Yamada"
},
"origin": "***.***.***.***",
"url": "https://httpbin.org/post"
}
-O
:リクエスト先の名前のファイルに出力
curl -O 'https://httpbin.org/get'
レスポンス
cat get # ファイル確認
{
"args": {},
"headers": {
"Accept": "*/*",
"Host": "httpbin.org",
"User-Agent": "curl/8.7.1",
"X-Amzn-Trace-Id": "Root=1-67c950b7-2631a9ab63e41c67359a222f"
},
"origin": "***.***.***.***",
"url": "https://httpbin.org/get"
}
POST
curl -X POST \
-H "content-type: application.json" \
-d '{"first_name":"Tarou","last_name":"Yamada","age":"20"}' \
-O 'https://httpbin.org/post'
レスポンス
cat post # ファイル確認
{
"args": {},
"data": "{\"first_name\":\"Tarou\",\"last_name\":\"Yamada\",\"age\":\"20\"}",
"files": {},
"form": {},
"headers": {
"Accept": "application/json",
"Content-Length": "54",
"Content-Type": "application/json",
"Host": "httpbin.org",
"User-Agent": "curl/8.7.1",
"X-Amzn-Trace-Id": "Root=1-67c95344-62b75b132391d41b78563221"
},
"json": {
"age": "20",
"first_name": "Tarou",
"last_name": "Yamada"
},
"origin": "***.***.***.***",
"url": "https://httpbin.org/post"
}
-s
:進行状況・エラー・警告を非表示
GET
# 間違ったURL
curl -s 'https://httpbin/get';
レスポンス
# レスポンス
# 出力は空になる。
POST
# 間違ったURL
curl -X POST \
-H "content-type: application.json" \
-d '{"first_name":"Tarou","last_name":"Yamada","age":"20"}' \
-s 'https://httpbin/post'
レスポンス
# レスポンス
# 出力は空になる。
-f
:400以上のレスポンスコードを返す
curlでは400以上のエラーが返されても表示してくれません。
-f
オプションを使用すれば、表示されます。
GET
curl -f 'https://httpbin.org/status/404'
レスポンス
curl: (56) The requested URL returned error: 404
POST
curl -X POST \
-H "content-type: application.json" \
-d '{"first_name":"Tarou","last_name":"Yamada","age":"20"}' \
-f 'https://httpbin.org/status/505'
レスポンス
curl: (56) The requested URL returned error: 505
おわりに
実際にコマンドを叩いてみると、どんなデータがリクエストとして送られ、レスポンスとして返ってくるのかわかりやすかったです。
curlには今回紹介したオプション以外にも、大量のオプションが存在しています。
今後の業務では認証周りを触ることになりそうなので、そのあたりのコマンドも学習していこうと思います。
参考資料