Google workflowsで外部のAPIからデータを取得してみる
はじめに
データアナリティクス事業本部のkobayashiです。
GoogleCloudのWorkflowsではGoogleCloudのリソースの操作を各Stepで行うこともできますが、外部のAPIからデータを取得してそのレスポンスを扱うこともできます。今回は外部のAPIからデータを取得して表示してみたのでまとめます。
WorkflowsでHTTP リクエストを行う
WorkflowsではHTTPエンドポイントに対してHTTPリクエストの呼び出しを行うことができます。公式ドキュメントの冒頭には
たとえば、HTTP リクエストを介して Cloud Functions や Cloud Run などの Google Cloud サービスを呼び出すことができます。
となっていますが、GoogleCloud以外の外部HTTPエンドポイントに対してもリクエストを行うことももちろんできます。
では早速試してみます。
Workflowsで外部のHTTPエンドポイントを呼び出してみる
今回呼び出してみるHTTPエンドポイントは気象庁のエリアごとの週間天気予報を取得するAPIになります。
https://www.jma.go.jp/bosai/forecast/data/forecast/{都道府県・エリアコード}.json
このAPIで取得できるのは以下のようなJSONになります。
レスポンスのサンプル
[
{
"publishingOffice": "熊谷地方気象台",
"reportDatetime": "2024-09-26T17:00:00+09:00",
"timeSeries": [
{
"areas": [
{
"area": {
"code": "110020",
"name": "北部"
},
"weatherCodes": [
"200",
"203",
"203"
],
"weathers": [
"くもり",
"くもり 時々 雨 所により 昼前 から 夜のはじめ頃 雷を伴い 激しく 降る",
"くもり 時々 雨"
],
"winds": [
"南東の風",
"北西の風 後 北の風",
"北西の風"
]
},
{
"area": {
"code": "110010",
"name": "南部"
},
"weatherCodes": [
"200",
"203",
"203"
],
"weathers": [
"くもり",
"くもり 時々 雨 所により 昼前 から 夜のはじめ頃 雷を伴い 激しく 降る",
"くもり 時々 雨"
],
"winds": [
"南東の風",
"北の風 後 やや強く",
"北の風"
]
},
{
"area": {
"code": "110030",
"name": "秩父地方"
},
"weatherCodes": [
"200",
"203",
"203"
],
"weathers": [
"くもり",
"くもり 時々 雨 所により 昼前 から 夜のはじめ頃 雷を伴い 激しく 降る",
"くもり 時々 雨"
],
"winds": [
"東の風 後 南西の風",
"北の風 後 東の風",
"西の風"
]
}
],
"timeDefines": [
"2024-09-26T17:00:00+09:00",
"2024-09-27T00:00:00+09:00",
"2024-09-28T00:00:00+09:00"
]
},
{
"areas": [
{
"area": {
"code": "110020",
"name": "北部"
},
"pops": [
"10",
"30",
"70",
"70",
"60"
]
},
{
"area": {
"code": "110010",
"name": "南部"
},
"pops": [
"10",
"30",
"70",
"70",
"60"
]
},
{
"area": {
"code": "110030",
"name": "秩父地方"
},
"pops": [
"20",
"30",
"70",
"70",
"60"
]
}
],
"timeDefines": [
"2024-09-26T18:00:00+09:00",
"2024-09-27T00:00:00+09:00",
"2024-09-27T06:00:00+09:00",
"2024-09-27T12:00:00+09:00",
"2024-09-27T18:00:00+09:00"
]
},
{
"areas": [
{
"area": {
"code": "43056",
"name": "熊谷"
},
"temps": [
"22",
"25"
]
},
{
"area": {
"code": "43241",
"name": "さいたま"
},
"temps": [
"22",
"24"
]
},
{
"area": {
"code": "43156",
"name": "秩父"
},
"temps": [
"20",
"24"
]
}
],
"timeDefines": [
"2024-09-27T00:00:00+09:00",
"2024-09-27T09:00:00+09:00"
]
}
]
},
{
"precipAverage": {
"areas": [
{
"area": {
"code": "43056",
"name": "熊谷"
},
"max": "45.7",
"min": "15.5"
}
]
},
"publishingOffice": "熊谷地方気象台",
"reportDatetime": "2024-09-26T17:00:00+09:00",
"tempAverage": {
"areas": [
{
"area": {
"code": "43056",
"name": "熊谷"
},
"max": "24.9",
"min": "16.9"
}
]
},
"timeSeries": [
{
"areas": [
{
"area": {
"code": "110000",
"name": "埼玉県"
},
"pops": [
"",
"80",
"50",
"40",
"30",
"40",
"50"
],
"reliabilities": [
"",
"",
"C",
"B",
"A",
"B",
"C"
],
"weatherCodes": [
"203",
"203",
"202",
"200",
"201",
"200",
"202"
]
}
],
"timeDefines": [
"2024-09-27T00:00:00+09:00",
"2024-09-28T00:00:00+09:00",
"2024-09-29T00:00:00+09:00",
"2024-09-30T00:00:00+09:00",
"2024-10-01T00:00:00+09:00",
"2024-10-02T00:00:00+09:00",
"2024-10-03T00:00:00+09:00"
]
},
{
"areas": [
{
"area": {
"code": "43056",
"name": "熊谷"
},
"tempsMax": [
"",
"26",
"27",
"29",
"30",
"30",
"25"
],
"tempsMaxLower": [
"",
"25",
"23",
"26",
"27",
"27",
"23"
],
"tempsMaxUpper": [
"",
"33",
"31",
"31",
"33",
"33",
"31"
],
"tempsMin": [
"",
"20",
"20",
"21",
"21",
"22",
"20"
],
"tempsMinLower": [
"",
"19",
"19",
"19",
"19",
"19",
"16"
],
"tempsMinUpper": [
"",
"23",
"22",
"22",
"23",
"24",
"24"
]
}
],
"timeDefines": [
"2024-09-27T00:00:00+09:00",
"2024-09-28T00:00:00+09:00",
"2024-09-29T00:00:00+09:00",
"2024-09-30T00:00:00+09:00",
"2024-10-01T00:00:00+09:00",
"2024-10-02T00:00:00+09:00",
"2024-10-03T00:00:00+09:00"
]
}
]
}
]
この中から都道府県・エリアごとの1週間の天気コード[1].timeSeries.areas[].weatherCodes
を取得してみます。
以下が外部APIからデータを取得してlogとして表示するWorkflowsになります。
main:
steps:
- init:
assign:
- prefs:
100000: 群馬県
110000: 埼玉県
120000: 千葉県
130000: 東京都
140000: 神奈川県
- loop_prefs:
for:
value: pref_code
in: ${keys(prefs)}
steps:
- call_api:
call: http.get
args:
url: ${"https://www.jma.go.jp/bosai/forecast/data/forecast/" + pref_code + ".json"}
result: result_api
- loop_area:
for:
value: v
in: ${result_api.body[1].timeSeries[0].areas}
steps:
- logging_area:
call: sys.log
args:
text: ${v.area.code + ":" + v.area.name}
severity: INFO
- logging_area_data:
call: sys.log
args:
text: ${v.weatherCodes}
severity: INFO
- the_end:
return: ${prefs}
いくつかStepがありますので解説します。
始めにinit
ステップで1週間の天気予報を取得する都道府県・エリアコードをMapで定義しています。
次にloop_prefs
で定義した都道府県・エリアコードに対するHTTPエンドポイントにリクエストを行っています。
loop_prefs
の中ではループごとにStepが有り始めに都道府県・エリアコードに対するHTTPエンドポイントにリクエストを行い、その結果から[1].timeSeries.areas[]
を取得し、更にそれをloop_area
としてループし最終的にほしいエリア名[1].timeSeries.areas[].area.name
と天気コード[1].timeSeries.areas[].weatherCodes
を取得してログに出力しています。
これを可視化すると次のようなものになります。
ではこれをDeployして実行してみます。
$ gcloud workflows deploy wf-http --source=wf-http.yml --location asia-northeast1
$ gcloud workflows run wf-http --location asia-northeast1
argument: 'null'
createTime: '2024-09-29T12:23:49.895005423Z'
duration: 3.774371777s
endTime: '2024-09-29T12:23:53.669377200Z'
name: projects/{プロジェクトID}/locations/asia-northeast1/workflows/wf-http/executions/ded8d075-76f9-4338-85ed-eca954b968cd
result: '{"100000":"群馬県","110000":"埼玉県","120000":"千葉県","130000":"東京都","140000":"神奈川県"}'
startTime: '2024-09-29T12:23:49.895005423Z'
state: SUCCEEDED
status:
currentSteps:
- routine: main
step: the_end
workflowRevisionId: 000016-c77
ではログを表示してみます。
想定通りにエリア名と1週間の天気コードを取得できていることがわかります。
まとめ
GoogleCloudのWorkflowsで外部のAPIからデータを取得してそのレスポンスを扱ってみました。StepでHTTPリクエストを設定でき、レスポンスデータもJson型なら簡単に扱えるのでとても便利です。今回はエラーハンドルを行っていませんがレスポンスのステータスコードでエラーハンドルもできるのでかなり汎用性は高いと思いました。
最後まで読んで頂いてありがとうございました。