iimon TECH BLOG

iimonエンジニアが得られた経験や知識を共有して世の中をイイモンにしていくためのブログです

curlコマンドでHTTPリクエストを投げてみる

■ はじめに

株式会社iimonでフロントエンドエンジニをやっています「白水」です。

業務でAPIにリクエスト投げて、レスポンスが正しく返ってくるのか試す機会があったので、curlコマンドについて調べたことを書いていきます。

curlコマンドとは?

cURLとは、LinuxなどのUNIX系OSでよく利用されるコマンドラインツールの一つで、URLで示されるネットワーク上の場所に対して様々なプロトコル(通信手順)を用いてアクセスできるもの。オープンソースソフトウェアとして公開されている。

curlclient for URL)コマンドは、いろんなプロトコルを使用してリクエスト送ることができるコマンドです。

HTTPのGETやPOSTはもちろん、HTTPSFTPなどいろんな通信プロトコルをサポートしています。

cURLとは - IT用語辞典

curlコマンドが使えるか確認

❯ curl --version
curl 7.88.1 (x86_64-apple-darwin22.0) libcurl/7.88.1 (SecureTransport) LibreSSL/3.3.6 zlib/1.2.11 nghttp2/1.51.0
Release-Date: 2023-02-20
Protocols: dict file ftp ftps gopher gophers http https imap imaps 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 NTLM_WB SPNEGO SSL threadsafe UnixSockets

curl --versionコマンドで、上記のような情報が返ってきたら、curlコマンドが使える状態です。

Protocolsという部分に、利用できるプロトコルが表示されています。

curlの基本の使い方(GETリクエスト)

curl {URL}

curlコマンドの基本形は上記の通りです。

試しに、Dog APIにリクエストを投げてみます。

赤枠で囲っている部分がAPIのリクエスト先のため、この部分にリクエストを投げて見ます。

❯ curl 'https://dog.ceo/api/breeds/list/all'
{"message":{"affenpinscher":[],"african":[],"airedale":[],"akita":[],"appenzeller":[],"australian":["shepherd"],"basenji":[],"beagle":[],"bluetick":[],"borzoi":[],"bouvier":[],"boxer":[],"brabancon":[],"briard":[],"buhund":["norwegian"],"bulldog":["boston","english","french"],"bullterrier":["staffordshire"],"cattledog":["australian"],"chihuahua":[],"chow":[],"clumber":[],"cockapoo":[],"collie":["border"],"coonhound":[],"corgi":["cardigan"],"cotondetulear":[],"dachshund":[],"dalmatian":[],"dane":["great"],"deerhound":["scottish"],"dhole":[],"dingo":[],"doberman":[],"elkhound":["norwegian"],"entlebucher":[],"eskimo":[],"finnish":["lapphund"],"frise":["bichon"],"germanshepherd":[],"greyhound":["italian"],"groenendael":[],"havanese":[],"hound":["afghan","basset","blood","english","ibizan","plott","walker"],"husky":[],"keeshond":[],"kelpie":[],"komondor":[],"kuvasz":[],"labradoodle":[],"labrador":[],"leonberg":[],"lhasa":[],"malamute":[],"malinois":[],"maltese":[],"mastiff":["bull","english","tibetan"],"mexicanhairless":[],"mix":[],"mountain":["bernese","swiss"],"newfoundland":[],"otterhound":[],"ovcharka":["caucasian"],"papillon":[],"pekinese":[],"pembroke":[],"pinscher":["miniature"],"pitbull":[],"pointer":["german","germanlonghair"],"pomeranian":[],"poodle":["medium","miniature","standard","toy"],"pug":[],"puggle":[],"pyrenees":[],"redbone":[],"retriever":["chesapeake","curly","flatcoated","golden"],"ridgeback":["rhodesian"],"rottweiler":[],"saluki":[],"samoyed":[],"schipperke":[],"schnauzer":["giant","miniature"],"segugio":["italian"],"setter":["english","gordon","irish"],"sharpei":[],"sheepdog":["english","shetland"],"shiba":[],"shihtzu":[],"spaniel":["blenheim","brittany","cocker","irish","japanese","sussex","welsh"],"spitz":["japanese"],"springer":["english"],"stbernard":[],"terrier":["american","australian","bedlington","border","cairn","dandie","fox","irish","kerryblue","lakeland","norfolk","norwich","patterdale","russell","scottish","sealyham","silky","tibetan","toy","welsh","westhighland","wheaten","yorkshire"],"tervuren":[],"vizsla":[],"waterdog":["spanish"],"weimaraner":[],"whippet":[],"wolfhound":["irish"]},"status":"success"}%

APIを叩いてみると、APIドキュメントに記載があるJSONデータと同じレスポンスが返ってきていることがわかります。

今回はJSONでデータが返ってきましたが、HTMLも当然返ってきます。

❯ curl 'http://abehiroshi.la.coocan.jp/'

以下、HPにcurlでリクエストを投げると、HTMLが返ってきます。

http://abehiroshi.la.coocan.jp/

❯ curl 'https://dog.ceo/api/breeds/list/all' | jq

brew install jqでjqをインストールして、| jqを追加すると、JSONデータを見やすく表示してくれます。

jqコマンドでjsonから必要なデータのみを取得する - Qiita

curlコマンドにオプションをつけて実行してみる

curlコマンドに色々なオプションをつけることができるので、オプションをつけてリクエストを投げてみます。

curlコマンドを試すのにおすすめのサイトがhttpbin.orgです。

こちらは、リクエストを投げると、いろいろなレスポンスを返してくれるサイトです。

リクエストの書き方が正しいか?

きちんとHTTP通信を行えるものなのか?

を確認できます。

◆ -Xオプションで、リクエストメソッドを指定する

❯ curl -X GET 'http://httpbin.org/get'

{
  "args": {},
  "headers": {
    "Accept": "*/*",
    "Host": "httpbin.org",
    "User-Agent": "curl/7.88.1",
    "X-Amzn-Trace-Id": "Root=1-64b3f1af-35ec57f664ec7af373174521"
  },
  "origin": "60.111.23.142",
  "url": "http://httpbin.org/get"
}

-Xの後に「GET」や「POST」を指定すると、リクエストメソッドを明示的に指定して、リクエストを投げることができます。

❯ curl -X POST 'http://httpbin.org/post'
{
  "args": {},
  "data": "",
  "files": {},
  "form": {},
  "headers": {
    "Accept": "*/*",
    "Host": "httpbin.org",
    "User-Agent": "curl/7.88.1",
    "X-Amzn-Trace-Id": "Root=1-64b3f22c-142a99e75e5217477cd0ce33"
  },
  "json": null,
  "origin": "60.111.23.142",
  "url": "http://httpbin.org/post"
}

POSTメソッドの場合は、curl -X POST {URL}のような感じです。

-Hでパラメータを追加

❯ curl -X POST 'http://httpbin.org/post' -H 'accept: application/json'

{
  "args": {},
  "data": "",
  "files": {},
  "form": {},
  "headers": {
    "Accept": "application/json", // ここが変化する
    "Host": "httpbin.org",
    "User-Agent": "curl/7.88.1",
    "X-Amzn-Trace-Id": "Root=1-64b3f2ba-694651dc73f4614b142ff0ba"
  },
  "json": null,
  "origin": "60.111.23.142",
  "url": "http://httpbin.org/post"
}

-H ‘パラメータ名: 値’をつけることで、HTTPヘッダを追加することができます。

"Accept"の値が"application/json"に変化していることがわかります。

❯ curl -X GET "https://httpbin.org/bearer" -H "accept: application/json" -H "Authorization: 12345678"

トークン認証を使用するAPIにアクセスする場合は、ヘッダーにトークンを追加してリクエストを送信します。

◆ -dオプションでPOSTリクエストで送信するデータを指定

❯ curl -X POST 'http://httpbin.org/post' -H 'content-type: application/json' -d '{"hoge": "fuga", "key": "value"}'
{
  "args": {},
  "data": "{\"hoge\": \"fuga\", \"key\": \"value\"}", // -dオプションの値
  "files": {},
  "form": {},
  "headers": {
    "Accept": "*/*",
    "Content-Length": "32",
    "Content-Type": "application/json", // -H オプションの値
    "Host": "httpbin.org",
    "User-Agent": "curl/7.88.1",
    "X-Amzn-Trace-Id": "Root=1-64b3f3ce-321c23f04808868b5201745c"
  },
  "json": {
    "hoge": "fuga",
    "key": "value"
  },
  "origin": "60.111.23.142",
  "url": "http://httpbin.org/post"
}

-dの後にPOSTリクエストで送信するデータを指定すると、そのデータを送ることができます。

今回はJSON形式のデータをPOSTしています。

◆ -v オプションでHTTP通信の詳細を出力する

❯ curl -v 'http://httpbin.org/post' -H 'content-type: application/json' -d '{"key": "value"}'

*   Trying x.x.x.x:x...
* Connected to httpbin.org (54.211.216.104) port 80 (#0)
> POST /post HTTP/1.1
> Host: httpbin.org
> User-Agent: curl/7.88.1
> Accept: */*
> content-type: application/json
> Content-Length: 16
>
< HTTP/1.1 200 OK
< Date: Sun, 16 Jul 2023 13:50:28 GMT
< Content-Type: application/json
< Content-Length: 428
< Connection: keep-alive
< Server: gunicorn/19.9.0
< Access-Control-Allow-Origin: *
< Access-Control-Allow-Credentials: true
<

{
  "args": {},
  "data": "{\"key\": \"value\"}",
  "files": {},
  "form": {},
  "headers": {
    "Accept": "*/*",
    "Content-Length": "16",
    "Content-Type": "application/json",
    "Host": "httpbin.org",
    "User-Agent": "curl/7.88.1",
    "X-Amzn-Trace-Id": "Root=1-64b3f5a4-4b03b5c739fc512b1328d97a"
  },
  "json": {
    "key": "value"
  },
  "origin": "60.111.23.142",
  "url": "http://httpbin.org/post"
}
* Connection #0 to host httpbin.org left intact

-fオプションで成功、失敗を判断する

❯ curl -X POST "http://httpbin.org/status/400"

curlコマンドでエラーになるAPIを叩いてみます。

そうすると、何も表示されません。

curlコマンドは、エラーになっても正常に終了したような気を持たせる性質があります。

❯ echo $?
0

ちなみに、echo $0という特殊変数を出力すると、直前に打ったコマンドが成功したか、失敗したかを数字で表してくれます。

  • コマンド成功時には「0」
  • 失敗時には「1」

が特殊変数に設定されます。

終了ステータス | UNIX & Linux コマンド・シェルスクリプト リファレンス

❯ cat hogehoge.html
cat: hogehoge: No such file or directory

❯ echo $?
1

そのため、存在しないファイルを開いた後に、echo $?と入力すると、失敗しているので「1」と表示されます。

❯ curl -f -X POST "http://httpbin.org/status/400"
curl: (22) The requested URL returned error: 400

で、先ほどのcurlコマンドでは失敗しているにも関わらず、何も表示されません。

そこで、-fオプションを付与すると、きちんとエラーを出してくれます。

◆ 実行結果をファイルに出力する

❯ curl 'http://abehiroshi.la.coocan.jp/' > sample.txt

❯ cat sample.txt

> sample.txtでファイルの出力先とファイル名を指定すると、レスポンスをファイルに出力できます。

ブラウザからcurlコマンドをコピー

curlコマンドの公式をみると、オプションが複数あり、Cookie情報とか10個ほど設定しないといけなくてめんどくさいと思いますが、curlコマンドは簡単に作れます。

curlでリクエストを投げたいページのNETWORKを開いて、 Copy > Copy as cURLをクリックして、それをターミナルn貼り付ければ、終わりです。

Postman

postmanというアプリを使うと、curlと同様にHTTPリクエストを投げることができます。

https://www.xlsoft.com/jp/blog/blog/2017/06/23/post-1638-post-1638/

■ 参考資料

curl - How To Use