背景
graphqlとはサーバーのAPIの記述方式の1つです。動作確認時のコマンドを組み立てるのがなかなか手間だったので、備忘録として内容を記事に残します。
紹介するコマンドは下記のログ取りサーバーの動作確認のために作りました。
clj-server-practice
作ったコマンド全体
コマンドの全体はこちらです。ubuntu22.04のbashで動作を確認しました。
AUTH_BEARER="XXYYZZ"
HOST=http://localhost:3000
function escape_str () {
echo "$1" | sed 's/\\/\\\\/g' | sed 's/\"/\\"/g'
}
WHERE="[{\"key\": [\"data\", \"camera_id\"], \"action\": \"not_null\"}]"
ESCAPED_WHERE=$(escape_str "$WHERE")
ORDER="[{\"key\": \"created_at\", \"dir\": \"desc\"}]"
ESCAPED_ORDER=$(escape_str "$ORDER")
QUERY="{ raw_device_logs(where: \"$ESCAPED_WHERE\", order: \"$ESCAPED_ORDER\") { total } } }"
ESCAPED_QUERY=$(escape_str "$QUERY")
JSON="{\"query\": \"$ESCAPED_QUERY\"}"
RECEIVED_JSON=$(curl -X POST ${HOST}/graphql \
-H "Authorization: Bearer $AUTH_BEARER" \
-H "Content-Type: application/json" \
-d "$JSON")
echo $RECEIVED_JSON
要所を解説します。
graphQLのリクエストはjsonのqueryキーに必要な情報を記述してpostする
jsonのqueryキーにgraphqlのquery(取得したい情報)の文字列を渡します。HOST=http://localhost:3000
curl -X POST ${HOST}/graphql \
-H "Content-Type: application/json" \
-d "{\"query\": \"{ raw_device_logs { total } }\"}"
文字列なので、query内部で文字列を扱う場合はダブルクオートやバックスペースなどのエスケープ(文字列の中で表示する文字列の形式に変換)が必要です。
HOST=http://localhost:3000
curl -X POST ${HOST}/graphql \
-H "Content-Type: application/json" \
-d "{\"query\": \"{ raw_device_logs(where: \\\"[{\\\\\\\"key\\\\\\\": [\\\\\\\"data\\\\\\\", \\\\\\\"camera_id\\\\\\\"], \\\\\\\"action\\\\\\\": \\\\\\\"not_null\\\\\\\"}]\\\", order: \\\"[{\\\\\\\"key\\\\\\\": \\\\\\\"created_at\\\\\\\", \\\\\\\"dir\\\\\\\": \\\\\\\"desc\\\\\\\"}]\\\") { total } } }\"}"
上記のような3階層以上の文字列エスケープは手動入力が困難なほど「\」が多いです。
bashでの文字列エスケープは関数を作って使うのが便利
echoとsedコマンドを組み合わせて文字列エスケープを行う関数を作り、必要な箇所で呼びました。(bashのShell Parameter Expansion( ${STR//a/b} で aをbに変えられる表現)も試しましたが、2回連続で処理する記述方法は無さそうだったので、今回はecho1回とsed2回で関数を組みました。)
function escape_str () {
echo "$1" | sed 's/\\/\\\\/g' | sed 's/\"/\\"/g'
}
これを使うことで、「\」の数の把握が困難な階層のエスケープも手動入力に比べて楽に作れます。
WHERE="[{\"key\": [\"data\", \"camera_id\"], \"action\": \"not_null\"}]"
ESCAPED_WHERE=$(escape_str "$WHERE")
ORDER="[{\"key\": \"created_at\", \"dir\": \"desc\"}]"
ESCAPED_ORDER=$(escape_str "$ORDER")
QUERY="{ raw_device_logs(where: \"$ESCAPED_WHERE\", order: \"$ESCAPED_ORDER\") { total } } }"
ESCAPED_QUERY=$(escape_str "$QUERY")
JSON="{\"query\": \"$ESCAPED_QUERY\"}"
echo $JSON
{"query": "{ raw_device_logs(where: \"[{\\\"key\\\": [\\\"data\\\", \\\"camera_id\\\"], \\\"action\\\": \\\"not_null\\\"}]\", order: \"[{\\\"key\\\": \\\"created_at\\\", \\\"dir\\\": \\\"desc\\\"}]\") { total } } }"}
更に良い書き方や便利コマンドがあれば、コメントなどで教えていただけると嬉しいです。
必要に応じてヘッダに認証情報を追加
curlコマンドなので、一般的なAPIのpostと同様に必要があれば認証情報を付与できます。AUTH_BEARER="XXYYZZ"
curl -X POST ${HOST}/graphql \
-H "Authorization: Bearer $AUTH_BEARER" \
-H "Content-Type: application/json" \
-d "$JSON"
おわり
graphql動作確認用のcurlコマンドを作って動かせました。エスケープの「\」が多かったの人力でのコマンドを組み立ては早々諦めてbash芸に集中しました。
この記事の情報がコマンドでgraphqlの動作確認をcurlで行いたい人(将来の自分も含む)の助けになれば嬉しいです。
参考
公式のREADMEです。GraphQLでの呼び出しの作成
今回は使わなくなりましたが、bashの変数の文字列を置き換える表現の関連情報です。
echo | sedなんていらなかったんだ!
Replace one substring for another string in shell script
Shell Parameter Expansion
bashの関数で変数を扱うには$1や$2を使えば良いと把握したフォーラムです。
Passing parameters to a Bash function
0 件のコメント :
コメントを投稿