Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
Help us understand the problem. What is going on with this article?

curlコマンドでapiを叩く

はじめに

curlコマンドを使ってapiを叩いたりするのですが、curlコマンドってただapiを叩くためのコマンドなの?みたいなレベル感でした。
業務で使ったコマンドを簡略化すると下記になるのですが、オプションの意味とかよくわからなかったので勉強がてらまとめてメモしました。

curl -k -v -A "アプリのユーザーエージェント" "uri" | jq

参考にしたサイトは下記のマニュアル
https://curl.haxx.se/docs/manpage.html

curlコマンドとは

curlコマンドとはサーバから、もしくはサーバへデータ転送を行うコマンドです。
curlコマンド自体はapiを叩くためだけに存在しているわけではないです。

httpリクエストができるコマンドなのかなーって思ってたのですが、実際には
HTTPやHTTPSといったプロトコルに対応しているため、GETでAPIを叩いたりすることができるというだけで、
curlコマンド自体はFTP,SFTP,LDAP,TELNETなど多くのプロトコルに対応しています。

下記の書式でコマンドが実行できます。

curl [options] [URL]

jqコマンド

curlとは関係ないが、curlでapiを叩く時に一緒に使うと便利です。
jqコマンドは入力を受け取り、出力を生成するフィルタの役割を果たします。

特定のデータを抽出したり整形したりできるのですが、今回は整形して見やすくするためだけに使用します。

インストールはhomebrewでできます。

brew install jq

実際に何が違うかというと
jqコマンドなし

echo '{"message": null, "results": [{"address1": "高知県", "address2": "南国市"}], "status": 200}';

{"message": null, "results": [{"address1": "高知県", "address2": "南国市"}], "status": 200}

jqコマンドあり

echo '{"message": null, "results": [{"address1": "高知県", "address2": "南国市"}], "status": 200}' | jq;

{
  "message": null,
  "results": [
    {
      "address1": "高知県",
      "address2": "南国市"
    }
  ],
  "status": 200
}

もう少し詳しい内容についてはこちらに書きましたのでよければ合わせてご確認ください。
jqコマンドでjsonから必要なデータのみを取得する

便利なオプション

HTTPヘッダを出力させる

「-i」 HTTP ヘッダを出力に含めます。
「-I」 HTTP ヘッダのみを取得します。

curl -I "http://zipcloud.ibsnet.co.jp/api/search?zipcode=7830060"

HTTP/1.1 200 OK
Content-Type: text/plain; charset=utf-8
X-Cloud-Trace-Context: f49b7a1f7109801bca6e70de691430a3
Date: Sat, 17 Dec 2016 05:37:51 GMT
Server: Google Frontend
Content-Length: 290

ちなみにjqコマンドとの併用はできない

curl -I "http://zipcloud.ibsnet.co.jp/api/search?zipcode=7830060" | jq 

parse error: Invalid numeric literal at line 1, column 9

jqコマンドで扱える形式はjsonだからです。

リクエストのヘッダとレスポンスのヘッダを表示する

「-v」を指定することで、リクエストとレスポンスのヘッダを表示できます。

ユーザーエージェントを指定

「-A」 "ユーザーエージェント" を指定することで、特定のユーザーエージェントでのリクエストであると認識されます。
例えばアプリからAPIを叩く挙動を確認したい時に使用できます。

curl -A "ユーザーエージェント" "http://zipcloud.ibsnet.co.jp/api/search?zipcode=7830060"

SSL/TLSのエラーをスキップする

「-k」を指定するとSSL/TLSのエラーをスキップできます。(安全でないSSL/TLS接続を行う)
オレオレ証明書なんかを使用している時に「-k」オプションをつけます。

オレオレ証明書とは

正式には自己署名証明書と呼ばれています。
公開鍵に署名をする際に、その公開鍵に対応した秘密鍵で署名を行った公開鍵証明書のことです。
通常はサーバ証明書は「信頼できる認証機関」が署名を行うのですが、それを自分で署名を行っているため、オレオレ証明書と呼ばれています。

POST

APIに対してPOSTでリクエストを行う場合には-X POSTを指定する。
パラメータをつけてPOSTでリクエストを行う場合には、-dでパラメータを指定する。

curl -X POST [url] -d "name=hoge"
curl -X POST [url] -d "name=hoge&age=20"

結果に応じてコマンドを実行

Software Designでcurlコマンドの使い方が紹介されていたのですが、特定の結果が返ってきた場合に何かコマンドを実行させる(再起動など)という使い方もあるそうです。

$ curl --silent "http://zipcloud.ibsnet.co.jp/api/search?zipcode=7830060"
{
    "message": null,
    "results": [
        {
            "address1": "高知県",
            "address2": "南国市",
            "address3": "蛍が丘",
            "kana1": "コウチケン",
            "kana2": "ナンコクシ",
            "kana3": "ホタルガオカ",
            "prefcode": "39",
            "zipcode": "7830060"
        }
    ],
    "status": 200
}
$ curl --silent "http://zipcloud.ibsnet.co.jp/api/search?zipcode=7830060" | grep "北海道" >/dev/null 2>&1 && echo "hoge"
$ curl --silent "http://zipcloud.ibsnet.co.jp/api/search?zipcode=7830060" | grep "高知県" >/dev/null 2>&1 && echo "hoge"
hoge

その他

関連するものをいろいろと

改行

curlに限ったことではありませんし、なにを当たり前のことをと言われそうですが、昔の自分は知らなかったので
オプションをいくつかつけていると、長くなってしまうため \ で改行するとわかりやすいです。

$ curl -s -X GET "url" \
    -H "accept: application/json" \
    -H "toke: *****" \
    -H "id: *****" | jq

jqコマンドで必要なデータのみを取得する

先ほどのzipcodeのレスポンスから、address1だけを抜き出したい場合は下記のように書くことができます。
APIのレスポンスで一部のデータのみ知りたい場合はうまく使えると見やすくなりますね!

$ curl --silent "http://zipcloud.ibsnet.co.jp/api/search?zipcode=7830060" \
  | jq -c '.results[] | [.address1]'
["高知県"]

詳細はこちらが参考になるかなと思います!
jqを活用してAPIレスポンス等から欲しい情報だけを抽出する【中級編】

下位10%のダメなエンジニアにだけ解けないパズル

前に話題になったらしい問題です。こちらから試せます。
最低限のcurlの知識があればできるのでやってみてください。
正解が欲しい方は下位10%の〜で検索してもらえればいろいろと出てくると思います。

Postman

Chromeの拡張機能として提供されています。
Postman

json形式で記載されている仕様書があり、それをコマンドにするよりも、そのままコピペしたかったのでこちらを使用していました。
登録もできるので、よく使うものはこちらに登録するのも良いと思います。

スクリーンショット 2018-02-01 19.45.07.png

IDEのHTTPクライアント

PhpStormを使っているのでPhpStormのHTTPクライアントを使っています。
コード補完もしてくれるので便利です。詳細は下記のドキュメントを確認してください。
PhpStormコードエディタのHTTPクライアント
Image from Gyazo

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

デベロッパーツールのネットワークから、一番上のリクエストを選択して右クリックをします。(chrome)
copy as curlを選択するとcookie情報等もオプションで指定されたcurlコマンドを生成してくれます。

Screen Shot 2020-09-19 at 10.57.59.png

curl 'https://qiita.com/' \
  -H 'Upgrade-Insecure-Requests: 1' \
  -H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.102 Safari/537.36' \
  --compressed

スニペットツール

apiを作るときに自分で開発期間中に何度かapiを叩くことがあります。
その都度書くのはめんどくさいので、Clipyというスニペットツールに登録をしていつでもすぐにapiを叩けるようにしていました。(最近はHTTPクライアント使ってます)
【参考】クリップボード拡張Macアプリ「Clipy」を公開しました

まとめ

オプション数はかなり多いので、使うときは色々と調べながらやると良いですね。
これに限った話ではありません、同じコマンドをなんども書かないようなツールの選定や工夫も必要だなと書いてて改めて思いました。

yyphp
PHPerが毎週集まり、ざっくばらんに情報交換する雑談コミュニティ
https://yyphp.connpass.com/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away