프론트엔드 개발자의 경우,
가끔 백엔드의 API Response 값이 snake_case
일 경우 어떻게 관리할 지에 대해 고민에 빠지게 됩니다.
저도 오늘 같은 상황을 겪게 되었는데,
이번엔 네이밍 컨벤션을 맞춰주기로 했습니다.
컨벤션을 맞추는 데에는 여러가지 방법이 있겠지만,
고민 끝에 저는 axios
의 interceptor
를 통해 해결을 해보았습니다.
전체적인 프로세스는 두 가지입니다.
하나는 공용으로 사용하는 instance에 interceptor
를 붙이는 것,
하나는 넘겨받은 object의 key들을 CamelCase
로 변경하는 함수를 작성하는 것이 되겠습니다.
먼저 interceptor
를 붙여봅시다.
import axios from 'axios'
const client = axios.create({
withCredentials: true,
})
client.interceptors.response.use((response) => {
response.dataOriginal = JSON.parse(JSON.stringify(response.data))
return response
})
export default client
혹시 모를 경우를 위해 오리지널 데이터를 따로 복제해둡시다.
이번엔 object의 key들을 CamelCase
로 변경하는 함수를 작성해보겠습니다.
export const objectKeysToCamelCase = (ob = {}, isDeep = true) => {
return Object.entries(ob).reduce((acc, [key, value]) => {
const keyComputed = key.replace(/(_.?)/g, (matches) => matches[1].toUpperCase())
let result
if (isDeep === false || !value || typeof value !== 'object') {
result = value
} else if (Array.isArray(value)) {
result = value.map((item) => objectKeysToCamelCase(item, isDeep))
} else {
result = objectKeysToCamelCase(value, isDeep)
}
acc[keyComputed] = result
return acc
}, {})
}
저는 유틸리티성 함수들을 따로 모아 관리하고 있어서 export
가 포함되어있는데,
만약 하나의 파일에서 진행하신다면, 굳이 넣지 않으셔도 됩니다.
함수를 조금 설명하자면, API Response 값의 경우 대부분 여러 depth가 존재할 텐데, 이를 위해 재귀함수로 구성하였습니다.
만약 2번째 파라미터인 isDeep이 참이라면,
depth 1 뿐만 아니라 하위 depth까지 object가 존재하는지 탐색하고 key의 컨벤션들을 CamelCase
로 변환시켜줍니다.
반대로 거짓일 경우엔 depth 1의 key 값들만 변환시켜주겠지요 ?
이렇게 네이밍컨벤션을 변환해주는 함수를 만들었다면, 아래와 같이 적용시켜줍시다.
import axios from 'axios'
import { objectKeysToCamelCase } from '../util'
const client = axios.create({
withCredentials: true,
})
client.interceptors.response.use((response) => {
response.dataOriginal = JSON.parse(JSON.stringify(response.data))
response.data = objectKeysToCamelCase(response.data)
return response
})
export default client
그 후 확인해보면,
적용이 잘 된 것을 확인해볼 수 있습니다.
하지만 여기서 뭔가 찜찜한 기분이 드는데,
퍼포먼스에 대한 이슈입니다.
아무래도 모든 요소의 key와 value를 탐색하고, 비교 한 뒤 새로운 객체를 생성하는데, 걱정이 안 될 수가 없습니다.
그래서 한번 ... 테스트를 시도해보았습니다.
import axios from 'axios'
import { objectKeysToCamelCase } from '../util'
const client = axios.create({
withCredentials: true,
})
client.interceptors.response.use((response) => {
console.time()
response.dataOriginal = JSON.parse(JSON.stringify(response.data))
response.data = objectKeysToCamelCase(response.data)
console.timeEnd()
return response
})
export default client
단순히 response가 도착한 후 interceptor
가 받아 들일 때부터 넘겨줄 때까지의 시간을 재어봤는데요.
다행히도 이 과정에 0.017초 가량 소요된 것을 알 수 있었습니다.