JavaScript · TypeScript · API 境界
Axios snake_case ↔ camelCase
frontend と backend の命名規則が異なる場合、property rename を各所に散らさず1つの HTTP 境界で変換します。
JSON 向け再帰 key mapper を作る
function isPlainObject(value) {
return Object.prototype.toString.call(value) === "[object Object]"
}
function toCamelKey(key) { return key.replace(/_+([a-zA-Z0-9])/g, (_, char) => char.toUpperCase()) }
function toSnakeKey(key) { return key.replace(/([a-z0-9])([A-Z])/g, "$1_$2").replace(/[-\s]+/g, "_").toLowerCase() }
function mapKeys(value, keyMapper) {
if (Array.isArray(value)) return value.map((item) => mapKeys(item, keyMapper))
if (!isPlainObject(value)) return value
const output = {}
for (const [key, child] of Object.entries(value)) {
const nextKey = keyMapper(key)
if (Object.hasOwn(output, nextKey)) throw new Error(`Key collision: ${nextKey}`)
output[nextKey] = mapKeys(child, keyMapper)
}
return output
}plain JSON object と array だけを変換し、scalar や非 plain value は保持し、衝突を検出します。
専用 Axios instance に request/response interceptor を追加
import axios from "axios"
const api = axios.create({ baseURL: "/api" })
api.interceptors.request.use((config) => {
if (config.data && isPlainObject(config.data)) config.data = mapKeys(config.data, toSnakeKey)
if (config.params && isPlainObject(config.params)) config.params = mapKeys(config.params, toSnakeKey)
return config
})
api.interceptors.response.use((response) => {
response.data = mapKeys(response.data, toCamelKey)
return response
})request data/params を snake_case、response.data を camelCase に正規化します。
application code は camelCase のまま保つ
const response = await api.post("/users", {
displayName: "Ada Lovelace",
profileSettings: { emailNotifications: true },
})
console.log(response.data.createdAt)adapter を Axios instance に集約すれば UI と TypeScript model は1つの内部規則を保てます。
本番利用時の注意点
- FormData、Blob、ArrayBuffer、stream、class instance を JSON として再帰変換しないでください。
- 一部 endpoint が変換不要なら専用 instance または opt-out を用意します。
- header は同じ object-key mapper に通さないでください。
- TypeScript type は runtime key を変えないため interceptor が実際に data を変換する必要があります。
JSON 境界をオンラインでテスト
ネスト、配列、除外キー、stop path、接頭辞、衝突、key-only diff をブラウザで確認できます。
.json ファイルをドロップ、または端末から選択
ファイルはブラウザ内でのみ読み取ります。最大 5 MB。
変換後 JSON
{
"userProfile": {
"firstName": "Ada",
"createdAt": "2026-09-12"
}
}解析、ファイル読み込み、整形、キー変換はすべてブラウザ内で実行されます。JSON 入力は変換サーバーへ送信されません。