· HARUBOUYA · dataflow · 14 min read
お天気APIをECサイトに出すまでのデータフロー
天気に合わせた接客を出したいです。ブラウザから直接APIを叩くとリクエスト数が読めず費用も跳ねます。日次でまとめて取得し、CSVに整形して置く構成と、決めておくべき仕様を書きます。

「雨の日に、雨向けの商品をおすすめしたい」という要望はよく出ます。やること自体は単純で、天気を取ってきて、それに合わせて表示を変えるだけです。
ただしどこで天気を取るかを間違えると、費用と安定性の両方で困ります。ここでは実際に組んだ構成と、決めておくべき仕様を書きます。
問題:ブラウザから直接APIを叩く構成
最初に思いつくのは、サイトを開いた人のブラウザから気象APIを呼ぶ方式です。位置情報を取り、その場で天気を問い合わせ、結果に応じて表示を変えます。
動きはしますが、次の問題があります。
| 問題 | 内容 |
|---|---|
| リクエスト数が読めません | アクセス数に比例して増えます。キャンペーンで急増すると一気に跳ねます |
| 上限超過 | 気象APIには契約上のリクエスト上限があります。超えると止まります |
| 費用が読めません | 従量課金のため、月末まで金額が確定しません |
| APIキーが見えます | ブラウザから呼ぶ以上、キーは画面の裏側に置くことになります |
最後の点は特に大きいです。ブラウザの開発者ツールで F12 キー → Network タブ を開けば、送信されているリクエストのヘッダーが誰でも見られます。そこにAPIキーが載っていれば、そのまま第三者に使われます。
仕組み:サーバー側で1日1回取る
解決は単純で、取得する場所をブラウザからサーバーに移します。
| 区分 | 構成 |
|---|---|
| 変更前 | 訪問者のブラウザが、そのつど気象APIを呼びます |
| 変更後 | サーバーが1日1回まとめて取得し、クラウドストレージに置きます。接客ツールはその置いたファイルを読みます |
これでリクエスト数が固定されます。
| 項目 | 値 |
|---|---|
| 対象地点 | 約140地点(気象庁の一次細分区域に相当する単位) |
| 取得する種類 | 日別予報・時間別予報の2種 |
| 実行頻度 | 1日1回 |
| 月間リクエスト数 | 140 × 2 × 31 ≒ 約8,700件 |
アクセス数がどれだけ増えても、この数は変わりません。費用が事前に確定することが、この構成の最大の利点です。
全体の流れ
Cloud Scheduler(毎日2:30に起動)
↓
Cloud Workflows(全体の順番を管理)
↓
Cloud Run ①:気象APIを呼び、取得結果を中間バケットへ
↓
Cloud Run ②:中間バケットのファイルをCSVに変換し、公開用バケットへ配置
↓
接客ツール:CSVを日次で取り込み → 天気セグメントを作る → 接客を出す各段の役割は次の通りです。
| 順 | サービス | 役割 |
|---|---|---|
| 1 | Cloud Scheduler | 時刻を決めて起動する。設定はcron形式(例 30 2 * * *) |
| 2 | Cloud Workflows | 「①が成功したら②」という順番と、失敗時の扱いを定義します |
| 3 | Cloud Run ① | 気象APIを呼ぶ処理。APIキーはこのコンテナの中だけに持ちます |
| 4 | Cloud Run ② | 取得データを接客ツールが読める形のCSVに変換し、所定のパスへ置きます |
| 5 | 接客ツール | 置かれたCSVを取り込み、条件に合う人へ表示を出します |
全体の実行時間は5分程度です。接客の開始時刻から逆算して起動時刻を決めます。朝3時に最新データが揃っている必要があるなら、2時半に起動して余裕を持たせます。
Cloud Run を2つに分ける理由
1つにまとめても動きます。分けている理由は、失敗したときにどちらで失敗したかが分かるためです。
気象API側の障害で取得できなかったのか、変換処理のバグで壊れたのかは、原因も対処もまったく違います。分けておけば、ログを見るまでもなく切り分けられます。
決めておくこと
1. 地点の粒度と識別子
天気は地点ごとに違います。何地点を持つかで、データ量も接客の精度も変わります。
| 粒度 | 地点数の目安 | 向き不向き |
|---|---|---|
| 都道府県 | 47 | 粗いです。南北に長い県では実態と合いません |
| 一次細分区域 | 約140 | 実用的。天気予報で使われる単位と一致します |
| 市区町村 | 約1,700 | 細かいですが、リクエスト数と保守が跳ね上がります |
識別子は地名ではなくコードを使います。地名は表記ゆれが起きるうえ、同じ名前の市町村が存在します。地域メッシュコードのような、数値で一意に決まるものを Key にします。
2. CSVの仕様
接客ツール側が読む仕様に合わせます。実際に使っている形は次の通りです。
| カラム | 内容 |
|---|---|
| メッシュコード | 地点の識別子。これをKeyにします |
| 地名 | 表示用。市区町村役場の名称を使います |
| 都道府県名 | 絞り込み用 |
| 1時間ごとの予報 | JSONを文字列にしたもの |
| 1日ごとの予報 | JSONを文字列にしたもの |
| 更新日時 | バッチを実行した時刻 |
作成ルールも先に決めておきます。
- 文字コードは UTF-8
- ヘッダ行あり
- JSONを入れた列だけ、全体を
"で括ります。JSON内部の"は""と二重にしてエスケープします - JSON部分に改行を入れません。1レコードは必ず1行に収めます
- 更新日時は、予報の基準時刻ではなくバッチを実行した時刻を入れます
最後の2点が、実際にハマる場所です。JSONに改行が混ざると、CSVとしては別レコードに見えるため取り込みが崩れます。更新日時に予報の基準時刻を入れてしまうと、「データが今日更新されたか」が判定できなくなります。
3. 時刻の扱い
日時はUTCで持つか、日本時間で持つかを最初に決めて、全体で統一します。
起動時刻は日本時間、ファイル名の日付は日本時間、更新日時はUTC、という状態になりやすいです。どれが正解ということはありませんが、混在していると「昨日のファイルが置かれている」ように見える障害の切り分けができなくなります。
4. 置き場所とファイル名
gs://<バケット名>/weather/weather_YYYYMMDD.csv日付をファイル名に入れます。上書きにしないことで、過去分が残り、障害時にどのデータで接客していたかを追えます。
失敗例
実際に起きたものを含めて挙げます。
| 失敗 | 何が起きるか | 対処 |
|---|---|---|
| 1地点だけデータが欠落 | 特定地域の人に接客が出ません。誰も気づきません | 出力前にレコード件数を検査します。想定と違えば処理を止めます |
| 識別子が重複していました | 別の市のデータで上書きされます | マスタ側で一意性を検査してから使います |
| APIキーをフロントに書きます | 開発者ツールから見えます | キーはサーバー側の処理の中だけに持ちます。シークレット管理機能を使います |
| 日時の単位が混在 | 「今日のデータがない」に見える障害が切り分けできません | 保持する形式を1つに決め、変換は表示の直前だけで行います |
| 配置が接客開始に間に合いません | 前日のデータで接客が出ます | 開始時刻から逆算し、実行時間の3倍以上の余裕を取ります |
| リトライを入れていません | APIの一時的なエラーで、その日1日データがありません | 取得処理にリトライを設定します。失敗したらログを出して止めます |
件数の検査だけは必ず入れます。天気データは見た目が正常でも中身が欠けていることがあり、接客が出ないことに誰も気づかないまま数日過ぎます。
やること
起動時刻を設定する
- Google Cloud コンソールで「Cloud Scheduler」を開きます
- 「ジョブを作成」を押します
- 「頻度」に cron 形式で入力する(毎日2時30分なら
30 2 * * *) - 「タイムゾーン」で「日本標準時(JST)」を選びます
- 起動先として Workflows を指定します
タイムゾーンの指定を忘れるとUTCで動きます。日本時間より9時間ずれるため、設定直後に一度手動で実行して、動いた時刻を確認します。
動いたかを確認する
- Cloud Workflows の画面で対象のワークフローを開きます
- 「実行」タブを見ます
- 直近の実行が「成功」になっているかを確認します
失敗している場合は、その行を開くとどのステップで止まったかが表示されます。
出力されたファイルを確認する
- Cloud Storage の画面で対象のバケットを開きます
- 当日の日付のファイルがあるかを見ます
- ファイルサイズが前日と大きく違わないかを見ます
サイズが極端に小さければ、取得が途中で失敗しています。
まとめ
- 天気を取る場所をブラウザからサーバーへ移すだけで、リクエスト数と費用が固定されます
- 1日1回、全地点をまとめて取得し、CSVにしてストレージへ置きます。接客ツールはそれを読むだけ
- 地点の識別子は地名ではなくコードを使います。表記ゆれと重複を避けるため
- 日時の形式は最初に1つへ統一します。混在が障害切り分けを一番難しくします
- 出力前の件数検査を必ず入れます。欠落は見た目では分かりません
- 起動時刻は接客の開始時刻から逆算し、実行時間の3倍以上の余裕を取ります
天気に限らず、外部APIを使った接客はこの形に落ち着きます。取りに行く回数を自分でコントロールできる場所に置く、というだけの話です。
参考になったら、いいねを押してください。





