<p><style_prompt>
{“role”: “SRE/DevOps Engineer”, “context”: “REST API response validation using curl and jq”, “technical_focus”: [“Error Handling”, “Bash Portability”, “JSON Parsing”, “Systemd Integration”], “style”: “Strict, Technical, Procedural”}</style_prompt></p>
<p>
本記事は**Geminiの出力をプロンプト工学で整理した業務ドラフト(未検証)**です。
# curlとjqを用いたAPIレスポンスの堅牢な自動検証とシステム監視の実装
### 【導入と前提】
REST APIの正常性とレスポンスデータの整合性を自動検証し、障害検知を堅牢化します。前提:Linux(Bash 4.4以降)、curl、jqがインストールされていること。
### 【処理フローと設計】
</p>
<div class="wp-block-merpress-mermaidjs diagram-source-mermaid"><pre class="mermaid">
graph TD
A[Start] --> B["curl: API Request with Retries"]
B --> C{"HTTP Status Code Check"}
C -->|Success 200| D["jq: JSON Schema/Value Validation"]
C -->|Fail| E["Error Handling & Logging"]
D -->|Valid| F["Normal Termination"]
D -->|Invalid| E
E --> G["Cleanup & Exit 1"]
</pre></div>
<p>
このフローでは、ネットワークの一時的な不安定さを`curl`のリトライ機能で吸収し、受信したデータの構造的妥当性を`jq`のフィルタリング機能で厳密に評価します。
### 【実装:堅牢な自動化スクリプト】
</p>
<div class="codehilite">
<pre data-enlighter-language="generic">#!/usr/bin/env bash
# 未定義変数の参照で停止、パイプラインの途中のエラーを拾う、エラー発生で即時終了
set -euo pipefail
# 設定項目
API_URL="https://api.example.com/v1/health"
EXPECTED_VERSION="1.2.0"
TMP_FILE=$(mktemp)
# 終了時に一時ファイルを確実に削除する
trap 'rm -f "$TMP_FILE"' EXIT
echo "[INFO] Checking API health: ${API_URL}"
# curlによるリクエスト実行
# -s: サイレントモード, -S: エラー時のみ表示, -f: HTTPエラーで終了コードを非ゼロにする
# -L: リダイレクト追従, --retry: 一時エラー時の再試行回数
RESPONSE_CODE=$(curl -s -S -f -L \
--retry 3 \
--retry-delay 2 \
-o "$TMP_FILE" \
-w "%{http_code}" \
"${API_URL}")
# HTTPステータスコードの確認(curl -fで制御しているが念押し)
if [ "$RESPONSE_CODE" -ne 200 ]; then
echo "[ERROR] API request failed with status: ${RESPONSE_CODE}" >&2
exit 1
fi
# jqによるJSONレスポンスの検証
# statusが'ok'かつversionが期待通りであることを確認
CHECK_RESULT=$(jq -r \
--arg req_ver "$EXPECTED_VERSION" \
'.status == "ok" and .version == $req_ver' \
"$TMP_FILE")
if [ "$CHECK_RESULT" != "true" ]; then
echo "[ERROR] API Response validation failed." >&2
echo "[DEBUG] Received JSON: $(cat "$TMP_FILE")" >&2
exit 1
fi
echo "[SUCCESS] API is healthy and version matches: ${EXPECTED_VERSION}"
</pre>
</div>
<p>
#### (参考)定期実行用Systemd Timer設定例
`/etc/systemd/system/api-check.timer`
</p>
<div class="codehilite">
<pre data-enlighter-language="generic">[Unit]
Description=Run API health check every 5 minutes
[Timer]
OnBootSec=1min
OnUnitActiveSec=5min
[Install]
WantedBy=timers.target
</pre>
</div>
<h3 class="wp-block-heading">【検証と運用】</h3>
<ol class="wp-block-list">
<p><li><p><strong>ドライラン実行</strong>: スクリプトに実行権限を付与し、手動で動作を確認します。
<code>chmod +x check_api.sh && ./check_api.sh</code></p></li>
<li><p><strong>ログの確認</strong>: <code>systemd</code>で運用する場合、標準出力・標準エラー出力は<code>journalctl</code>で追跡可能です。
<code>journalctl -u api-check.service -f</code></p></li>
<li><p><strong>異常系のシミュレーション</strong>: URLを無効なものに変え、リトライとエラーハンドリングが機能するか確認します。</p></li>
</p></ol>
<h3 class="wp-block-heading">【トラブルシューティングと落とし穴】</h3>
<ul class="wp-block-list">
<li><p><strong>PIPESTATUSの考慮</strong>: <code>pipefail</code>を有効にしていますが、複雑なパイプラインでは <code>${PIPESTATUS[@]}</code> を確認し、どのコマンドが失敗したか特定する必要がある場合があります。</p></li>
<li><p><strong>機密情報の露出</strong>: APIキーをスクリプト内にハードコードしないでください。環境変数や <code>~/.netrc</code>、またはシークレット管理ツールから取得するように設計してください。</p></li>
<li><p><strong>jqのパースエラー</strong>: 不完全なJSONを受け取った場合、<code>jq</code>自体がエラーを返します。この際も <code>set -e</code> によりスクリプトは安全に停止します。</p></li>
</ul>
<h3 class="wp-block-heading">【まとめ】</h3>
<p>運用の冪等性と堅牢性を維持するための3つのポイント:</p>
<ol class="wp-block-list">
<li><p><strong>エラー即時停止</strong>: <code>set -euo pipefail</code> で「予期せぬ成功」を防ぐ。</p></li>
<li><p><strong>リソースのクリーンアップ</strong>: <code>trap</code> を使い、異常終了時でも一時ファイルを残さない。</p></li>
<li><p><strong>外部リトライ</strong>: <code>curl</code> 自体のリトライ機能を使い、ネットワークの揺らぎに対する耐性を持たせる。</p></li>
</ol>
{“role”: “SRE/DevOps Engineer”, “context”: “REST API response validation using curl and jq”, “technical_focus”: [“Error Handling”, “Bash Portability”, “JSON Parsing”, “Systemd Integration”], “style”: “Strict, Technical, Procedural”}
本記事は**Geminiの出力をプロンプト工学で整理した業務ドラフト(未検証)**です。
# curlとjqを用いたAPIレスポンスの堅牢な自動検証とシステム監視の実装
### 【導入と前提】
REST APIの正常性とレスポンスデータの整合性を自動検証し、障害検知を堅牢化します。前提:Linux(Bash 4.4以降)、curl、jqがインストールされていること。
### 【処理フローと設計】
graph TD
A[Start] --> B["curl: API Request with Retries"]
B --> C{"HTTP Status Code Check"}
C -->|Success 200| D["jq: JSON Schema/Value Validation"]
C -->|Fail| E["Error Handling & Logging"]
D -->|Valid| F["Normal Termination"]
D -->|Invalid| E
E --> G["Cleanup & Exit 1"]
このフローでは、ネットワークの一時的な不安定さを`curl`のリトライ機能で吸収し、受信したデータの構造的妥当性を`jq`のフィルタリング機能で厳密に評価します。
### 【実装:堅牢な自動化スクリプト】
#!/usr/bin/env bash
# 未定義変数の参照で停止、パイプラインの途中のエラーを拾う、エラー発生で即時終了
set -euo pipefail
# 設定項目
API_URL="https://api.example.com/v1/health"
EXPECTED_VERSION="1.2.0"
TMP_FILE=$(mktemp)
# 終了時に一時ファイルを確実に削除する
trap 'rm -f "$TMP_FILE"' EXIT
echo "[INFO] Checking API health: ${API_URL}"
# curlによるリクエスト実行
# -s: サイレントモード, -S: エラー時のみ表示, -f: HTTPエラーで終了コードを非ゼロにする
# -L: リダイレクト追従, --retry: 一時エラー時の再試行回数
RESPONSE_CODE=$(curl -s -S -f -L \
--retry 3 \
--retry-delay 2 \
-o "$TMP_FILE" \
-w "%{http_code}" \
"${API_URL}")
# HTTPステータスコードの確認(curl -fで制御しているが念押し)
if [ "$RESPONSE_CODE" -ne 200 ]; then
echo "[ERROR] API request failed with status: ${RESPONSE_CODE}" >&2
exit 1
fi
# jqによるJSONレスポンスの検証
# statusが'ok'かつversionが期待通りであることを確認
CHECK_RESULT=$(jq -r \
--arg req_ver "$EXPECTED_VERSION" \
'.status == "ok" and .version == $req_ver' \
"$TMP_FILE")
if [ "$CHECK_RESULT" != "true" ]; then
echo "[ERROR] API Response validation failed." >&2
echo "[DEBUG] Received JSON: $(cat "$TMP_FILE")" >&2
exit 1
fi
echo "[SUCCESS] API is healthy and version matches: ${EXPECTED_VERSION}"
#### (参考)定期実行用Systemd Timer設定例
`/etc/systemd/system/api-check.timer`
[Unit]
Description=Run API health check every 5 minutes
[Timer]
OnBootSec=1min
OnUnitActiveSec=5min
[Install]
WantedBy=timers.target
【検証と運用】
ドライラン実行: スクリプトに実行権限を付与し、手動で動作を確認します。
chmod +x check_api.sh && ./check_api.sh
ログの確認: systemdで運用する場合、標準出力・標準エラー出力はjournalctlで追跡可能です。
journalctl -u api-check.service -f
異常系のシミュレーション: URLを無効なものに変え、リトライとエラーハンドリングが機能するか確認します。
【トラブルシューティングと落とし穴】
PIPESTATUSの考慮: pipefailを有効にしていますが、複雑なパイプラインでは ${PIPESTATUS[@]} を確認し、どのコマンドが失敗したか特定する必要がある場合があります。
機密情報の露出: APIキーをスクリプト内にハードコードしないでください。環境変数や ~/.netrc、またはシークレット管理ツールから取得するように設計してください。
jqのパースエラー: 不完全なJSONを受け取った場合、jq自体がエラーを返します。この際も set -e によりスクリプトは安全に停止します。
【まとめ】
運用の冪等性と堅牢性を維持するための3つのポイント:
エラー即時停止: set -euo pipefail で「予期せぬ成功」を防ぐ。
リソースのクリーンアップ: trap を使い、異常終了時でも一時ファイルを残さない。
外部リトライ: curl 自体のリトライ機能を使い、ネットワークの揺らぎに対する耐性を持たせる。
ライセンス:本記事のテキスト/コードは特記なき限り
CC BY 4.0 です。引用の際は出典URL(本ページ)を明記してください。
利用ポリシー もご参照ください。
コメント