Day 58:複数API連携 ― 「バラバラの情報」をひとつのデータにまとめる
Day 58では、複数のAPIを組み合わせて使う ことをテーマに、 実際に「複数APIデータ統合ツール」を作っていきます。
やりたいことはシンプルです。
- 複数のAPIからデータを取得する
- それぞれの結果を「ひとつのまとまったデータ」に統合する
- ツールとして、毎回同じ流れで使える形にする
Web・APIの世界では、 「1つの画面を作るために、裏側で複数のAPIを呼んでいる」 というのはよくある話です。
今日は、その裏側の流れをPythonで再現してみましょう。
複数API連携のイメージを言葉で整理する
ひとつの「統合データ」を作るシナリオ
まずは、どんなAPIを組み合わせるか、 イメージしやすいシナリオを決めます。
例として、次のような「ユーザー情報統合」を考えてみます。
- ユーザー基本情報API
name(名前)email(メールアドレス)
- ユーザー活動情報API
last_login(最終ログイン日時)login_count(ログイン回数)
- ユーザー購入情報API
last_order_id(最後の注文ID)total_spent(累計購入金額)
これらをまとめて、
{
"name": "Alice",
"email": "alice@example.com",
"last_login": "2024-01-01T12:34:56",
"login_count": 42,
"last_order_id": "ORD-12345",
"total_spent": 12345.67,
}
Pythonのような 統合されたユーザーデータ を作るイメージです。
サンプルAPIレスポンスを用意する(モックデータ)
実際のAPIの代わりに「モック関数」を使う
ここでは、実際の外部APIではなく、 「APIっぽい関数」 を使って説明していきます。
# day58_mock_apis.py
def fetch_user_profile(user_id: int) -> dict:
"""
ユーザー基本情報APIのモックです。
実際にはHTTPリクエストを送るところですが、ここでは固定データを返します。
"""
print(f"[API] ユーザー基本情報を取得します (user_id={user_id})")
return {
"user_id": user_id,
"name": "Alice",
"email": "alice@example.com",
}
def fetch_user_activity(user_id: int) -> dict:
"""
ユーザー活動情報APIのモックです。
"""
print(f"[API] ユーザー活動情報を取得します (user_id={user_id})")
return {
"user_id": user_id,
"last_login": "2024-01-01T12:34:56",
"login_count": 42,
}
def fetch_user_orders(user_id: int) -> dict:
"""
ユーザー購入情報APIのモックです。
"""
print(f"[API] ユーザー購入情報を取得します (user_id={user_id})")
return {
"user_id": user_id,
"last_order_id": "ORD-12345",
"total_spent": 12345.67,
}
Pythonこの3つの関数を「APIの代わり」として使いながら、 複数API連携の流れを組み立てていきます。
ステップ1:同期的に複数APIを呼び出して統合する
まずは「順番に呼んで、まとめる」基本形
最初のステップでは、 同期処理で順番にAPIを呼び出して統合する 流れを作ります。
# day58_sync_integration.py
from day58_mock_apis import (
fetch_user_profile,
fetch_user_activity,
fetch_user_orders,
)
def integrate_user_data_sync(user_id: int) -> dict:
"""
複数APIからユーザーデータを同期的に取得し、
ひとつの辞書に統合する関数です。
"""
print(f"[SYNC] ユーザーデータ統合を開始します (user_id={user_id})")
# 1. ユーザー基本情報を取得
profile = fetch_user_profile(user_id)
# 2. ユーザー活動情報を取得
activity = fetch_user_activity(user_id)
# 3. ユーザー購入情報を取得
orders = fetch_user_orders(user_id)
# 4. 統合データを作成
integrated = {
"user_id": user_id,
"name": profile["name"],
"email": profile["email"],
"last_login": activity["last_login"],
"login_count": activity["login_count"],
"last_order_id": orders["last_order_id"],
"total_spent": orders["total_spent"],
}
print("[SYNC] ユーザーデータ統合が完了しました。")
return integrated
def main():
user_id = 1
integrated_data = integrate_user_data_sync(user_id)
print("\n=== 統合されたユーザーデータ ===")
for key, value in integrated_data.items():
print(f"{key}: {value}")
if __name__ == "__main__":
main()
Pythonポイント:
- 3つのAPIを 順番に 呼び出しています。
- それぞれの結果から必要な項目を取り出して、ひとつの辞書にまとめています。
- 「統合ツール」として、
integrate_user_data_sync()が入口になっています。
この形は、まず「複数API連携の基本」を理解するにはとても分かりやすいです。
ステップ2:非同期版の複数API連携を考える
「待ち時間があるAPI」をまとめて呼びたいとき
Day 57で学んだように、 非同期処理は 「待っている時間をうまく使う」 ための仕組みです。
複数API連携では、
- 各APIのレスポンスを待っている時間
- ネットワークの待ち時間
が積み重なることが多いので、 非同期処理と相性が良い場面がたくさんあります。
ここでは、asyncio を使って 「非同期版のモックAPI」と「非同期統合関数」を作ってみます。
非同期モックAPIを用意する
async と await を使ったAPI風関数
# day58_async_mock_apis.py
import asyncio
async def fetch_user_profile_async(user_id: int) -> dict:
"""
非同期版のユーザー基本情報APIモックです。
asyncio.sleep() で「ネットワーク待ち」を模しています。
"""
print(f"[ASYNC API] ユーザー基本情報を取得します (user_id={user_id})")
await asyncio.sleep(1) # 1秒待つ(ネットワーク待ちのイメージ)
return {
"user_id": user_id,
"name": "Alice",
"email": "alice@example.com",
}
async def fetch_user_activity_async(user_id: int) -> dict:
"""
非同期版のユーザー活動情報APIモックです。
"""
print(f"[ASYNC API] ユーザー活動情報を取得します (user_id={user_id})")
await asyncio.sleep(1.5) # 1.5秒待つ
return {
"user_id": user_id,
"last_login": "2024-01-01T12:34:56",
"login_count": 42,
}
async def fetch_user_orders_async(user_id: int) -> dict:
"""
非同期版のユーザー購入情報APIモックです。
"""
print(f"[ASYNC API] ユーザー購入情報を取得します (user_id={user_id})")
await asyncio.sleep(2) # 2秒待つ
return {
"user_id": user_id,
"last_order_id": "ORD-12345",
"total_spent": 12345.67,
}
Pythonここでは、
await asyncio.sleep()を使って「ネットワーク待ち」を模しています。- 実際のHTTPクライアント(
aiohttpやhttpxの非同期版など)を使うときも、 同じようにawaitでレスポンスを待つ形になります。
非同期で複数APIをまとめて呼び出して統合する
asyncio.gather() で「まとめて待つ」
非同期版の統合関数では、 3つのAPIを ほぼ同時に呼び出して、まとめて待つ 形にしてみます。
# day58_async_integration.py
import asyncio
from day58_async_mock_apis import (
fetch_user_profile_async,
fetch_user_activity_async,
fetch_user_orders_async,
)
async def integrate_user_data_async(user_id: int) -> dict:
"""
複数APIからユーザーデータを非同期的に取得し、
ひとつの辞書に統合する関数です。
"""
print(f"[ASYNC] ユーザーデータ統合を開始します (user_id={user_id})")
# 3つのAPI呼び出しを「まとめて」スケジュールします。
profile_task = asyncio.create_task(fetch_user_profile_async(user_id))
activity_task = asyncio.create_task(fetch_user_activity_async(user_id))
orders_task = asyncio.create_task(fetch_user_orders_async(user_id))
# 3つのタスクがすべて完了するまで待ちます。
# asyncio.gather() を使うと、複数の await をまとめて扱えます。
profile, activity, orders = await asyncio.gather(
profile_task, activity_task, orders_task
)
# 統合データを作成します。
integrated = {
"user_id": user_id,
"name": profile["name"],
"email": profile["email"],
"last_login": activity["last_login"],
"login_count": activity["login_count"],
"last_order_id": orders["last_order_id"],
"total_spent": orders["total_spent"],
}
print("[ASYNC] ユーザーデータ統合が完了しました。")
return integrated
async def main_async():
user_id = 1
integrated_data = await integrate_user_data_async(user_id)
print("\n=== 統合されたユーザーデータ(非同期版) ===")
for key, value in integrated_data.items():
print(f"{key}: {value}")
if __name__ == "__main__":
asyncio.run(main_async())
Pythonポイント:
asyncio.create_task()で、3つのAPI呼び出しを「同時に走らせる」イメージでスケジュールしています。asyncio.gather()で、3つのタスクが全部終わるまで待ち、結果をまとめて受け取っています。- 統合のロジック自体は同期版とほぼ同じで、「取得方法だけが非同期になっている」形です。
実際のAPI呼び出しがそれぞれ1〜2秒かかるとすると、
- 同期版:1秒+1.5秒+2秒 ≒ 4.5秒
- 非同期版:最大の2秒にほぼ近い時間で完了
という違いが出てきます(あくまでイメージですが)。
複数APIデータ統合ツールの「使いやすい形」を整える
統合ツールとしての入口関数を用意する
複数API連携をツールとして使うときは、
- 統合処理を行う関数
- 結果を保存したり表示したりする部分
を分けておくと、後から拡張しやすくなります。
# day58_integration_tool.py
import asyncio
from day58_async_integration import integrate_user_data_async
from day58_sync_integration import integrate_user_data_sync
def run_sync_tool(user_id: int) -> None:
"""
同期版の複数APIデータ統合ツールを実行する関数です。
"""
print("=== 同期版 複数APIデータ統合ツール ===")
integrated = integrate_user_data_sync(user_id)
print("\n--- 統合結果(同期版) ---")
for key, value in integrated.items():
print(f"{key}: {value}")
async def run_async_tool(user_id: int) -> None:
"""
非同期版の複数APIデータ統合ツールを実行する関数です。
"""
print("=== 非同期版 複数APIデータ統合ツール ===")
integrated = await integrate_user_data_async(user_id)
print("\n--- 統合結果(非同期版) ---")
for key, value in integrated.items():
print(f"{key}: {value}")
def main():
user_id = 1
# 同期版ツールを実行
run_sync_tool(user_id)
print("\n")
# 非同期版ツールを実行
asyncio.run(run_async_tool(user_id))
if __name__ == "__main__":
main()
Pythonこの形にしておくと、
- 同期版と非同期版の違いを簡単に比較できる
- 将来的に「結果をCSV/JSON/SQLiteに保存する」処理を追加しやすい
- ツールとして「ユーザーIDを変えて実行する」などの拡張もしやすい
というメリットがあります。
Day 58ミニテンプレート:複数APIデータ統合ツールの基本形
最後に、Day 58の内容をコンパクトにまとめた 「複数APIデータ統合ツール」テンプレート を載せておきます。
# day58_multi_api_integration_template.py
import asyncio
async def fetch_api1(user_id: int) -> dict:
"""API1のモック。"""
await asyncio.sleep(1)
return {"user_id": user_id, "name": "Alice"}
async def fetch_api2(user_id: int) -> dict:
"""API2のモック。"""
await asyncio.sleep(1.5)
return {"user_id": user_id, "last_login": "2024-01-01T12:34:56"}
async def fetch_api3(user_id: int) -> dict:
"""API3のモック。"""
await asyncio.sleep(2)
return {"user_id": user_id, "total_spent": 12345.67}
async def integrate_multi_api(user_id: int) -> dict:
"""
複数APIからデータを取得して統合する基本テンプレートです。
"""
# 3つのAPI呼び出しをまとめてスケジュール
t1 = asyncio.create_task(fetch_api1(user_id))
t2 = asyncio.create_task(fetch_api2(user_id))
t3 = asyncio.create_task(fetch_api3(user_id))
# 3つの結果をまとめて待つ
r1, r2, r3 = await asyncio.gather(t1, t2, t3)
# 統合データを作成
integrated = {
"user_id": user_id,
"name": r1["name"],
"last_login": r2["last_login"],
"total_spent": r3["total_spent"],
}
return integrated
async def main_async():
user_id = 1
data = await integrate_multi_api(user_id)
print("=== 複数API統合結果 ===")
for key, value in data.items():
print(f"{key}: {value}")
if __name__ == "__main__":
asyncio.run(main_async())
Pythonこのテンプレートは、
- 複数API呼び出し
- 非同期処理 (
async/await) - 統合データの作成
という「複数API連携の基本セット」を、 コンパクトに体験できる形になっています。
Day 58のまとめ
Day 58では、複数API連携の基礎として、
- 複数のAPIからバラバラに返ってくる情報を、ひとつの「統合データ」にまとめる考え方
- 同期版として、順番にAPIを呼び出して統合する基本形
- 非同期版として、
async/awaitとasyncio.gather()を使って、複数APIをまとめて呼び出す形 - 「複数APIデータ統合ツール」として、統合処理をひとつの関数にまとめて使いやすくする形
を、コード例とともにステップバイステップで整理しました。
この土台があると、
- ユーザー情報+活動ログ+購入履歴をまとめたダッシュボード
- 複数の外部サービスからデータを集めて統合するレポートツール
- マイクロサービス間の連携を行う「集約API」
など、より実践的な「複数API連携」の世界へ、 自然にステップアップしていけるようになります。
