JavaScript · TypeScript · API 경계
Axios snake_case ↔ camelCase
property rename을 frontend 곳곳에 흩뿌리지 말고 하나의 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/non-plain value는 유지하며 collision을 감지합니다.
전용 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은 하나의 내부 규칙을 유지합니다.
프로덕션 고려사항
- FormData, Blob, ArrayBuffer, stream, class instance를 JSON처럼 재귀 변환하지 마세요.
- 변환이 필요 없는 endpoint에는 전용 instance나 opt-out을 사용하세요.
- header는 같은 object-key mapper에 통과시키지 마세요.
- TypeScript type은 runtime key를 바꾸지 않으므로 interceptor가 실제 데이터를 변환해야 합니다.
JSON 경계 온라인 테스트
중첩 객체, 배열, 제외 키, stop path, 접두사, 충돌, key-only diff를 구현 전에 확인하세요.
.json 파일을 놓거나 기기에서 선택
파일은 브라우저에서만 읽습니다. 최대 크기: 5 MB.
변환된 JSON
{
"userProfile": {
"firstName": "Ada",
"createdAt": "2026-09-12"
}
}파싱, 파일 읽기, 포맷 및 키 변환은 모두 브라우저에서 로컬로 실행됩니다. JSON 입력은 변환 서버로 전송되지 않습니다.