🐈
curl でステータスコードとBodyを一緒に返す
curl コマンドで WebAPI を呼び出すときにリクエストの Body だけでなくステータスコード(201, 403 など)も利用したいことがある。そのような時は、 curl コマンド実行時に -w "\n%{response_code}"
を付けて、 HTTP リクエストのステータスコードをコマンドの出力に追加する。
参考: https://everything.curl.dev/usingcurl/verbose/writeout
これを後で分割することでレスポンスの Body とステータスコードを両方利用できる。
サンプル:
RESULT=$(curl --url "https://goweather.herokuapp.com/weather/Sapporo" -w "\n%{response_code}")
RESULT_BODY=$(echo "${RESULT}" | sed "$ d")
RESULT_STATUS=$(echo "${RESULT}" | tail -n 1)
echo "Status: ${RESULT_STATUS}"
echo "Body: ${RESULT_BODY}"
実行結果:
Status: 200
Body: {"temperature":"-3 °C","wind":"4 km/h","description":"Light snow shower","forecast":[{"day":"1","temperature":"-4 °C","wind":"21 km/h"},{"day":"2","temperature":"-7 °C","wind":"7 km/h"},{"day":"3","temperature":"-4 °C","wind":"2 km/h"}]}
これを利用すると、 WebAPI を呼び出してリクエストの Body とステータスコードの両方を返す関数を以下のように定義できる。
ACCESS_TOKEN=XXXXXXXXXX
# WebAPI を呼び出し、その結果のステータスコードと Body を返す。
# @param $1: メソッド名(GET, POST, ...)
# @param $2: API パス(e.g., /users/<user_id>)
# @param $3: 結果を受け取るための変数名。ここで指定した名前の末尾に _BODY と _STATUS を付けた変数が作成される。
# @param $4: [optional] POST や PATCH のリクエスト時に送るデータ
function invoke_web_api {
local API_METHOD=$1
local API_PATH=$2
local VARIABLE_PREFIX=$3
local COMMAND="curl \
--header \"Content-Type: application/json\" \
--header \"Authorization: Bearer ${ACCESS_TOKEN}\" \
--request ${API_METHOD} \"https://example.com/v1${API_PATH}\" \
"
if [ $# -eq 4 ]; then
local DATA_PARAM=$(echo $4 | sed -e s/\\\"/\\\\\"/g)
COMMAND="${COMMAND} --data \"${DATA_PARAM}\""
fi
COMMAND="${COMMAND} -w \"\\n%{response_code}\""
local RESULT=$(eval "${COMMAND}")
if [ $? -ne 0 ]; then
echo "Failed to invoke."
exit 1
fi
local RESULT_BODY=$(echo "${RESULT}" | sed "$ d")
local RESULT_STATUS=$(echo "${RESULT}" | tail -n 1)
printf -v "${VARIABLE_PREFIX}_BODY" "%s" "${RESULT_BODY}"
printf -v "${VARIABLE_PREFIX}_STATUS" "%s" "${RESULT_STATUS}"
}
# ユーザーの一覧を取得
invoke_web_api GET "/users" GET_USERS
echo "GET_USERS_STATUS: ${GET_USERS_STATUS}"
echo "GET_USERS_BODY: ${GET_USERS_BODY}"
# 新しいユーザーを追加
invoke_web_api POST "/users" CREATE_USER \
"{ \"name\": \"John Lennon\", \"age\": 30 }"
echo "CREATE_USER_STATUS: ${CREATE_USER_STATUS}"
echo "CREATE_USER_BODY: ${CREATE_USER_BODY}"
Bash の printf
コマンドは printf -v "変数名"
のようにして指定した名前の変数を定義できるため、上の関数でその機能を利用している。
Discussion