camelCase, snake_case 변환하기

김범식·2024년 5월 6일
0
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;
	)	
}

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

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




해결

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

  1. camelCasesnakeCase로 변경
  2. 객체안에 객체가 존재해도 camelCasesnakeCase로 변경
  3. 배열로 이루어진 객체가 존재해도 camelCasesnakeCase로 변경
  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개의 댓글