Open3
React⇔Fast APIのAPI連携の実装方法を理解する

単位変換アプリでの具体例
バックエンド(FastAPI)の役割
- 変換の計算をする
- 結果をJSONで返す
from fastapi import FastAPI
app = FastAPI()
@app.get("/convert/length")
def convert_length(value: float, from_unit: str, to_unit: str):
# メートルを基準にした変換表
to_meter = {
"cm": 0.01,
"m": 1.0,
"km": 1000.0
}
# まずメートルに変換
meter_value = value * to_meter[from_unit]
# 目標の単位に変換
result = meter_value / to_meter[to_unit]
return {
"original_value": value,
"original_unit": from_unit,
"converted_value": result,
"converted_unit": to_unit
}
フロントエンドとバックエンドの連携
React(フロントエンド)
// 単位変換を行う関数
const convertUnit = async () => {
try {
// FastAPIのエンドポイントを呼び出し
const response = await fetch(
`http://localhost:8000/convert/length?value=100&from_unit=cm&to_unit=m`
);
// JSONデータを取得
const data = await response.json();
console.log(data); // { "converted_value": 1.0, ... }
// 結果を画面に表示
setResult(data.converted_value);
} catch (error) {
console.error('エラーが発生しました:', error);
}
};
4. データの流れを理解
ユーザー操作(React)
↓
「100cm を m に変換」ボタンクリック
↓
fetch()でAPIを呼び出し
↓
FastAPI「100cm → 1.0m」計算
↓
JSON形式で結果を返す
↓
Reactが結果を受け取り
↓
画面に「1.0m」と表示
5. サンプルコード
バックエンド(main.py):
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
app = FastAPI()
# React(localhost:3000)からのアクセスを許可
app.add_middleware(
CORSMiddleware,
allow_origins=["http://localhost:3000"],
allow_methods=["*"],
allow_headers=["*"],
)
@app.get("/convert")
def convert(value: float, from_unit: str, to_unit: str):
# 超シンプルな例:cm ↔ m
if from_unit == "cm" and to_unit == "m":
result = value / 100
elif from_unit == "m" and to_unit == "cm":
result = value * 100
else:
result = value # 同じ単位の場合
return {"result": result}
フロントエンド(App.tsx)
import React, { useState } from 'react';
function App() {
const [value, setValue] = useState<number>(0);
const [result, setResult] = useState<number>(0);
const handleConvert = async () => {
try {
const response = await fetch(
`http://localhost:8000/convert?value=${value}&from_unit=cm&to_unit=m`
);
const data = await response.json();
setResult(data.result);
} catch (error) {
console.error('エラー:', error);
}
};
return (
<div>
<input
type="number"
value={value}
onChange={(e) => setValue(Number(e.target.value))}
/>
<span>cm</span>
<button onClick={handleConvert}>変換</button>
<div>結果: {result}m</div>
</div>
);
}
export default App;

フロントエンド(React)側の詳細
ユーザーの入力を受け取る部分
function App() {
// ここに入力値を保存
const [inputValue, setInputValue] = useState<string>('');
const [result, setResult] = useState<string>('');
return (
<div>
{/* ユーザーが数値を入力 */}
<input
type="number"
value={inputValue}
onChange={(e) => setInputValue(e.target.value)}
placeholder="数値を入力"
/>
<span>cm</span>
<button onClick={handleConvert}>mに変換</button>
<div>結果: {result}m</div>
</div>
);
}
実際のデータの流れ
1. ユーザーが「150」と入力
↓
inputValue = "150" (Reactのstate)
2. 「変換」ボタンをクリック
↓
handleConvert関数が実行される
3. fetch()でAPIに送信
↓
http://localhost:8000/convert?value=150&from_unit=cm&to_unit=m
JSONでのやり取りについて
送信時(React → FastAPI):
// URLパラメータとして送信
const response = await fetch(
`http://localhost:8000/convert?value=${inputValue}&from_unit=cm&to_unit=m`
);
// または、POST形式でJSON送信
const response = await fetch('http://localhost:8000/convert', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
value: 150,
from_unit: 'cm',
to_unit: 'm'
})
});
受信時(FastAPI → React):
// FastAPIからのレスポンス(JSON形式の文字列)
// '{"result": 1.5, "original_value": 150, "unit": "m"}'
const data = await response.json(); // JSON文字列をJavaScriptオブジェクトに変換
console.log(data.result); // 1.5
console.log(data.unit); // "m"
コード例
import React, { useState } from 'react';
function App() {
const [inputValue, setInputValue] = useState<string>('');
const [result, setResult] = useState<string>('');
const [loading, setLoading] = useState<boolean>(false);
const handleConvert = async () => {
// 入力チェック
if (!inputValue || isNaN(Number(inputValue))) {
alert('数値を入力してください');
return;
}
setLoading(true); // ローディング開始
try {
// FastAPIに送信
const response = await fetch(
`http://localhost:8000/convert?value=${inputValue}&from_unit=cm&to_unit=m`
);
// レスポンスがOKか確認
if (!response.ok) {
throw new Error('API呼び出しに失敗しました');
}
// JSON形式のレスポンスを取得
const data = await response.json();
// 結果を画面に表示
setResult(data.result.toString());
} catch (error) {
console.error('エラー:', error);
alert('変換に失敗しました');
} finally {
setLoading(false); // ローディング終了
}
};
return (
<div>
<h1>単位変換アプリ</h1>
<input
type="number"
value={inputValue}
onChange={(e) => setInputValue(e.target.value)}
placeholder="数値を入力"
/>
<span>cm → </span>
<button
onClick={handleConvert}
disabled={loading}
>
{loading ? '変換中...' : 'mに変換'}
</button>
{result && (
<div>
<strong>結果: {result}m</strong>
</div>
)}
</div>
);
}
export default App;

FastAPI側の詳細解説
基本的な構造
from fastapi import FastAPI
# FastAPIのインスタンスを作成
app = FastAPI()
# この@app.get()が「エンドポイント」を作る
@app.get("/convert")
def convert_unit(value: float, from_unit: str, to_unit: str):
# ここで実際の処理を行う
result = value / 100 # cm → m の場合
# 辞書形式で返す → 自動的にJSONになる
return {
"original_value": value,
"original_unit": from_unit,
"result": result,
"result_unit": to_unit
}
エンドポイントって何?
一言で言うと「APIの窓口」
# http://localhost:8000/convert にアクセスできる窓口を作る
@app.get("/convert")
def convert_unit():
return {"message": "変換API"}
# http://localhost:8000/hello にアクセスできる窓口を作る
@app.get("/hello")
def say_hello():
return {"message": "Hello!"}
パラメータの受け取り方
URLパラメータで受け取る場合:
# http://localhost:8000/convert?value=100&from_unit=cm&to_unit=m
@app.get("/convert")
def convert_unit(value: float, from_unit: str, to_unit: str):
print(f"受け取った値: {value}") # 100.0
print(f"元の単位: {from_unit}") # "cm"
print(f"変換先単位: {to_unit}") # "m"
# 計算処理
if from_unit == "cm" and to_unit == "m":
result = value / 100
elif from_unit == "m" and to_unit == "cm":
result = value * 100
else:
result = value
return {"result": result}
単位変換の具体的な実装
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
app = FastAPI()
# React(localhost:3000)からのアクセスを許可
app.add_middleware(
CORSMiddleware,
allow_origins=["http://localhost:3000"], # Reactのサーバー
allow_methods=["*"],
allow_headers=["*"],
)
# 長さの変換表(メートル基準)
LENGTH_UNITS = {
"mm": 0.001,
"cm": 0.01,
"m": 1.0,
"km": 1000.0,
"inch": 0.0254,
"ft": 0.3048
}
@app.get("/convert/length")
def convert_length(value: float, from_unit: str, to_unit: str):
"""
長さの単位変換を行う
例: http://localhost:8000/convert/length?value=100&from_unit=cm&to_unit=m
"""
# エラーチェック
if from_unit not in LENGTH_UNITS:
return {"error": f"未対応の単位です: {from_unit}"}
if to_unit not in LENGTH_UNITS:
return {"error": f"未対応の単位です: {to_unit}"}
# 変換処理
# 1. まずメートルに変換
meter_value = value * LENGTH_UNITS[from_unit]
# 2. 目標の単位に変換
result = meter_value / LENGTH_UNITS[to_unit]
# 3. 結果をJSONで返す
return {
"success": True,
"original": {
"value": value,
"unit": from_unit
},
"converted": {
"value": round(result, 6), # 小数点6桁まで
"unit": to_unit
},
"calculation": f"{value} {from_unit} = {round(result, 6)} {to_unit}"
}
FastAPIが返すJSONの形
FastAPIのコード:
@app.get("/convert")
def convert_unit(value: float, from_unit: str, to_unit: str):
result = value / 100
# この辞書が自動的にJSONに変換される
return {
"original_value": value,
"result": result,
"status": "success"
}
実際にブラウザで受け取るJSON:
{
"original_value": 150.0,
"result": 1.5,
"status": "success"
}
エラーハンドリング
from fastapi import FastAPI, HTTPException
@app.get("/convert")
def convert_unit(value: float, from_unit: str, to_unit: str):
# 負の値チェック
if value < 0:
raise HTTPException(
status_code=400,
detail="値は0以上である必要があります"
)
# 対応していない単位のチェック
supported_units = ["cm", "m", "km"]
if from_unit not in supported_units:
raise HTTPException(
status_code=400,
detail=f"対応していない単位: {from_unit}"
)
# 正常な処理
result = value / 100
return {"result": result}
自動生成されるAPI仕様書
FastAPIのめちゃ便利機能!!
http://localhost:8000/docs
にアクセスすると、自動でAPI仕様書が表示されます!
処理の流れ(FastAPI側)
1. Reactから http://localhost:8000/convert?value=150&from_unit=cm&to_unit=m にリクエスト
↓
2. FastAPIが「@app.get("/convert")」の関数を実行
↓
3. パラメータを取得: value=150.0, from_unit="cm", to_unit="m"
↓
4. 計算処理: 150 ÷ 100 = 1.5
↓
5. 辞書を作成: {"result": 1.5, "original_value": 150.0}
↓
6. FastAPIが自動的にJSONに変換
↓
7. React側に送信: '{"result": 1.5, "original_value": 150.0}'