ふくふくHukuhuku Inc.
EP.10Data Fetch 9分公開: 2026-09-02

開発中に相手を叩きすぎない ── 応答を手元に貯める

コードを直しては実行、を繰り返すと、同じデータを何十回も取りに行くことになります。相手にも迷惑ですし、自分の待ち時間も無駄です。手元に貯めれば両方が解決します。

#Python#キャッシュ#開発
執筆 / 監修
松尾 亮合同会社ふくふく 代表社員

データ基盤・データパイプライン構築 / BI / 生成 AI 活用支援を専門とするエンジニア (28 年)。 本記事は AI 利用ポリシーに基づき、生成 AI の補助で執筆 → 人間が監修・編集して公開しています。

プロフィール詳細
シェア

取得処理を書いているとき、コードを直しては実行を繰り返します。整形の部分を直したいだけなのに、そのたびにを叩きに行く。1回3秒かかるなら、50回試せば150秒が待ち時間に消えます。相手のサーバも50回叩かれています

これはに引っかかる原因にもなります。本番の取得は1日1回でも、開発中は1時間に何十回も叩くので、開発のほうが本番より負荷が高いという逆転が起きます。手元に応答を貯めておけば、両方まとめて解決します。

遮断されると開発そのものが止まります。しかも遮断は一定時間で解けることも、手動で解除を頼むことになることもあり、後者だと数日単位で待たされます。開発の速さのために叩き続けた結果、開発ができなくなるという本末転倒が実際に起きます。

貯める仕組みを入れると、副作用としてネットワークが無くても開発を続けられます。移動中でも整形部分は書けますし、相手が計画停止していても手が止まりません。速さ以外にもこの利点があるので、書き捨てのコードでない限りは最初から入れておく価値があります。

同じ要求には貯めたものを返す

考え方は単純で、一度取った応答をファイルに保存しておき、次に同じ要求が来たら、相手に聞きに行かずに保存したものを返します。です。要求が同じかどうかは、URL とパラメータ、それに要求方法を組み合わせて判断します。

自前で書いてもいいのですが、requests を使っているなら、差し込むだけで貯めてくれる仕組みが用意されています。既存のコードをほとんど変えずに済むのが利点です。ただし何が貯まっているかが見えにくくなるので、最初は自分で書いて仕組みを把握しておくほうが、後で困りません。

取得部分を差し替えられる形にしておく。テストでも同じ形が使える
Python
import hashlibimport jsonfrom pathlib import Path
import requests
CACHE = Path(".cache/http")

def cache_key(url: str, params: dict | None) -> str:    blob = json.dumps({"url": url, "params": params or {}}, sort_keys=True)    return hashlib.sha256(blob.encode("utf-8")).hexdigest()[:32]

def get_json(url: str, params: dict | None = None, use_cache: bool = True):    """開発中は use_cache=True、本番は False で呼び分ける。"""    path = CACHE / f"{cache_key(url, params)}.json"    if use_cache and path.exists():        return json.loads(path.read_text(encoding="utf-8"))
    resp = requests.get(url, params=params, timeout=(5, 30))    resp.raise_for_status()    payload = resp.json()
    CACHE.mkdir(parents=True, exist_ok=True)    path.write_text(json.dumps(payload, ensure_ascii=False), encoding="utf-8")    return payload

貯めたものが古くなる問題

貯めると必ず「いつまで有効か」の問題が出ます。日次で更新されるデータを1週間前の応答で開発していた、という事故は起きます。整形のコードは正しいのに、出てくる数字が古い。

期限を持たせるのが基本です。日次更新のデータなら1日、確定した過去データなら無期限でも構いません。どの程度古くてよいかは、そのデータの性質で決まります。迷ったら短くしておいて、遅いと感じたら伸ばすほうが安全です。

もう一つ、貯めたものをまとめて捨てられるようにしておいてください。仕様が変わって応答の形が変わったとき、古い応答が残っていると、直したはずのコードが古い形で動き続けます。フォルダごと消せば済むようにしておけば、疑わしいときに迷わず捨てられます。

期限切れを判定して、古いものは取り直す
Python
import timefrom pathlib import Path

def is_fresh(path: Path, max_age_sec: float) -> bool:    """保存してからの経過時間で判断する。中身は見ない。"""    if not path.exists():        return False    return (time.time() - path.stat().st_mtime) < max_age_sec

def clear_cache(cache_dir: Path) -> int:    """疑わしいときは全部捨てる。消した件数を返す。"""    n = 0    for p in cache_dir.glob("*.json"):        p.unlink()        n += 1    return n
本番では貯めたものを使わない

開発を速くするための仕組みなので、本番の取得では素通しにするのが原則です。ここを切り替え忘れると、毎日同じ古いデータを保存し続けることになります。しかも例外が出ないので、気づくのは誰かが数字の異常に気づいたときです。

貯めてよくないもの

何でも貯めればいいわけではありません。認証を伴う応答は、貯める場所と期間に注意が要ります。個人情報を含む応答を手元のファイルに残せば、それは個人情報を持ち出したことになります。

  • 認証済みの個人データ — 貯めない。どうしても必要なら、伏せ字にしてから
  • トークンや鍵を含む応答 — 貯めない。と同じ扱いにする
  • 巨大な応答 — 手元の容量を食い潰す。上限を決めるか、対象を絞る

貯めた場所は、必ずリポジトリに入らないよう除外設定に加えておいてください。.cache のような名前にしておくと、うっかり追加してしまう事故を減らせます。

テストにも同じ形が使える

上のコードのように、取得部分を関数として切り出して差し替えられる形にしておくと、EP.08 で扱ったにそのまま流用できます。開発中に貯まった応答が、そのままテストの素材になるということです。

ただし、テストに使うものはリポジトリに入れるので、個人情報や鍵が含まれていないかを確認してから移す必要があります。開発用に貯めた場所と、テスト用に置く場所は分けておくのが安全です。次回は、取得を並行させる話をします。

シェア

この記事の感想を教えてください

あなたの 1 クリックで、本当にこの記事は更新されます。「もっと詳しく」「続編希望」が一定数集まった記事は、 ふくふくが 実際に内容を拡充したり続編記事を公開 します。 送信したリアクションはお使いのブラウザに記録され、再カウントされません。

シリーズの外も探す:

まずは、現状を聞かせてください。

要件が固まっていなくて大丈夫です。現状診断と方針提案までを無料でお手伝いします。

無料相談フォームへ hello [at] hukuhuku [dot] co [dot] jp