camelCase, snake_case 변환하기

김범식·2024년 5월 6일
post-thumbnail

문제

DB에서는 주로 데이터를 snakeCase로 다루는 경우가 많습니다. 보통 DB의 컬럼 이름을 지을 때 snakeCase를 사용하는 것이 일반적이기 때문입니다. 그에 반해 React에서는 변수 명을 지을 때 camelCase를 많이 사용합니다. 당장 useState를 사용하는 것만 봐도 camelCase를 사용하는 것을 볼 수 있습니다.

const [userInfo, setUserInfo] = useState({ userName:"이름", userEmail:"abc@email.com"})

카멜 케이스 (Camel Case) : userInfo, userEmail, isActive

스네이크 케이스 (Snake Case) : user_info, user_email, is_active




이렇게 네이밍 컨벤션이 서로 다르기 때문에 프로젝트를 진행하다 보면 서버에 데이터를 요청할 때 snakeCase로 오는 경우가 많았습니다. DB에서 꺼낸 그대로 넘겨주거나 혹은 변수 명을 변경해서 보내주더라도 snakeCase보내줄 때가 많았습니다.

//예시 데이터 
data : {
	user_name:"홍길동"
	user_email:"abc@email.com"
}

저는 frontend에서는 camelCase를 사용하는 게 편했기 때문에 다음처럼 변경해서 사용해 줘야 했습니다.

//예시 코드
function getUserInfo(data){
	const body = {
		user_name:data.userName,
		user_email:data.userEmail,
		}
	axios.get("https://도메인.com/api/userInfo",body)
	.then(res => {
		const data = {
				userName:res.data.userName
				userEmail:res.data.userEmail
	}
		return data;
	)	
}

요청을 보낼 때 그리고 응답을 받을 때, 두 번식 변수 명을 변경하다 보니 쓸대 없이 코드가 길어지고 코드가 길어진 만큼 실수가 많아졌습니다.

응답에 속성이 많으면 많을수록 변수 명을 변경하는 과정이 피곤하고 의미 없게 느껴졌습니다.




해결

camelCase와 snakeCase를 변환하는 함수를 만들어 이 문제를 해결하려 했고 함수의 역할을 다음과 같이 설정했습니다.

  1. camelCase를 snakeCase로 변경
  2. 객체안에 객체가 존재해도 camelCase를 snakeCase로 변경
  3. 배열로 이루어진 객체가 존재해도 camelCase 와 snakeCase로 변경
  4. 반대로 변환하는 것도 가능한 함수 추가 제작

camel → snake

function camelToSnake(obj: any): any {
  if (Array.isArray(obj)) {
  //객체 배열도 재귀로 해결
    return obj.map((v) => camelToSnake(v));
  } else if (obj !== null && obj.constructor === Object) {
    return Object.keys(obj).reduce((result: any, key: string) => {
      const snakeKey = key.replace(
        /[A-Z]/g,
        (matches) => "_" + matches.toLowerCase()
      );
        let value = obj[key];
        
       // 중첩된 객체에 대해 재귀적으로 camelToSnake함수 호출
      if (value !== null && typeof value === 'object') {
        value = camelToSnake(value);
      }
      
        
      result[snakeKey] = value;
      return result;
    }, {});
  }
  return obj;
}

snake→camel

export function snakeToCamel(obj: any): any {
  if (Array.isArray(obj)) {
    //객체 배열도 재귀로 해결
    return obj.map((v) => snakeToCamel(v));
  } else if (obj !== null && typeof obj === 'object') {
    return Object.keys(obj).reduce((result: any, key: string) => {
      let camelKey = key.replace(/([-_]\w)/g, (matches) => matches[1].toUpperCase());
      let value = obj[key];
      
      // 중첩된 객체에 대해 재귀적으로 snakeToCamel 함수 호출
      if (value !== null && typeof value === 'object') {
        value = snakeToCamel(value);
      }
      
      result[camelKey] = value;
      return result;
    }, {});
  }
  return obj;
}

다음과 같이 작성하면 함수의 재귀호출을 활용해서 객체의 배열, 그리고 객체안의 객체도 변수명을 모두 변환할 수 있습니다.!

//예시 코드
function getUserInfo(data){
	const body = camelToSnake(data)
	axios.get("https://도메인.com/api/userInfo",body)
	.then(res =>snakeToCamel(res.data))
}

더럽던 함수도 깔끔하게 바뀐 모습을 볼 수 있습니다.




느낀점


코드 컨벤션의 중요성을 느끼며, 앞으로는 프로젝트 초기에 코드 컨벤션을 명확히 정하고 따르는 것이 중요하다는 것을 배웠습니다.

profile
frontend developer

0개의 댓글