Fetch · JSON API 邊界
Fetch API snake_case ↔ camelCase
包裝 JSON Fetch 呼叫,讓應用程式物件維持 camelCase,而 wire format 維持 snake_case。
序列化前轉換 JSON 請求
import { keysToSnake } from "./api-case"
export async function postJson<T>(url: string, body: unknown): Promise<T> {
const response = await fetch(url, {
method: "POST",
headers: { "content-type": "application/json" },
body: JSON.stringify(keysToSnake(body)),
})
if (!response.ok) {
throw new Error(`API request failed: ${response.status}`)
}
return response.json() as Promise<T>
}先將應用程式物件轉成 snake_case,再呼叫 JSON.stringify。
回傳前轉換已解析回應
import { keysToCamel } from "./api-case"
export async function getJson<T>(url: string): Promise<T> {
const response = await fetch(url)
if (!response.ok) {
throw new Error(`API request failed: ${response.status}`)
}
const wireData: unknown = await response.json()
return keysToCamel(wireData) as T
}在 response.json() 後遞迴把鍵名轉成 camelCase,再回傳給呼叫端。
正式環境注意事項
- 只用於 JSON request/response endpoint;不要轉換 FormData、Blob、ArrayBuffer、stream 或檔案上傳。
- 在 response.json() 後轉換,不要處理原始文字,避免修改字串值。
- 若不同來源鍵可能正規化成同一結果鍵,請保留 collision detection。
- 把 wrapper 集中在共用 API client module,避免每個 component 重複轉換。
線上測試 JSON 邊界
在實作前測試巢狀物件、陣列、排除鍵、stop paths、語意前綴、衝突與 key-only diff。
拖放 .json 檔案,或從裝置選取
檔案只會在瀏覽器中讀取。最大檔案大小:5 MB。
轉換後 JSON
{
"userProfile": {
"firstName": "Ada",
"createdAt": "2026-09-12"
}
}解析、檔案讀取、格式化與鍵名轉換都在瀏覽器本機執行。JSON 不會傳送到轉換伺服器。