좋은 객체 ID(Object ID) 만들기

토스페이먼츠·2023년 7월 5일
16
post-thumbnail

해당 아티클은 토스페이먼츠 공식 블로그에서도 보실 수 있습니다.

객체 ID는 객체 지향 프로그래밍, 데이터베이스 관리, 네트워킹 등 다양한 컴퓨팅 환경에서 사용되는데요. 이 포스트에서는 좋은 객체 ID를 만들어야 하는 이유와 방법을 고유성과 식별 가능성을 중심으로 알아볼게요.

객체 ID(Object ID)란?

UUID의 구조

*객체 ID를 만들 때 사용하는 UUID의 구조 / 출처: https://www.mparticle.com/blog/what-is-a-uuid/

객체 ID는 말 그대로 객체를 구분하는 고유한 식별자(identifier)를 뜻해요. 객체 ID를 사용해서 특정 객체를 참조하거나 검색할 수 있죠. 객체 ID는 버그 추적, 로깅, 데이터 분석 등 다양한 상황에서 사용해요. 특정 이벤트나 문제가 발생했을 때 객체 ID로 관련 객체를 식별하고 문제의 원인을 찾을 수 있어요. 객체 ID가 중요한 이유죠.

객체 ID를 만들 때 고려할 점

중요한 객체 ID, 어떻게 만들면 좋을까요? 아래 세 가지를 고려해주세요.

  • 고유성: 동일한 시스템 또는 전체 네트워크 내에서 두 개 이상의 객체가 동일한 ID를 갖지 않는 것을 뜻해요. 객체 ID의 고유성은 데이터 무결성과 일관성을 보장하는 데 필요하죠.
  • 식별 가능성: 명확한 네이밍, 일관된 구조로 사용자가 예측할 수 있는 방식으로 객체 ID를 만드는 것을 뜻해요. 접두사(prefix)는 객체 ID에 추가적인 의미나 구분자를 제공하는데, 이를 통해 객체의 특성이나 속성을 나타내서 식별 가능성을 높일 수 있어요. 예를 들어 접두사 user-을 사용해서 객체 ID를 보고 사용자 객체임을 쉽게 인지할 수 있겠죠.
  • 보안성: 객체 ID는 사용자, 세션, 데이터 등을 고유하게 식별하기 때문에 악의적인 사용자가 이러한 ID를 추측하거나 탈취하여 부적절하게 사용하는 것을 방지하는 것이 중요해요. 그러려면 객체 ID는 예측할 수 없도록 랜덤해야 하죠. 순차적이거나 예측할 수 있는 ID를 사용하는 것보다 UUID를 사용하면 더 안전합니다. 랜덤한 정도 뿐 아니라 길이와 복잡성도 중요해요. 길고 문자, 숫자, 특수 문자 등이 혼합된 ID는 여러 정보가 조합되어 있기 때문에 추측하기 더 어려워요.

그럼, 이 중에서 고유성과 식별 가능성을 더 자세히 다뤄볼게요.

고유성: UUID vs. Hash 함수

객체 ID는 어떻게 “고유성”을 가질 수 있을까요? 객체 ID를 생성하는 방법에는 여러 가지가 있는데요, 가장 일반적인 방법은 UUID(Universally Unique Identifier)를 만들거나 Hash 함수를 사용하여 문자열을 생성하는 겁니다. 각 방식을 비교해 볼게요.

UUID와 Hash 함수 비교표

UUID는 랜덤하고 예측 불가능한 식별자가 필요할 때 유용하고, 해시 함수는 임의의 입력을 고정된 크기의 해시값으로 변환하는 데 주로 사용되기 때문에 항상 일관된 결과를 제공해야 하는 검색 작업에 사용될 때 유용해요. 보안 관련 요구 사항이 있다면 UUID 사용을, 검색이나 데이터 구조에 활용하고자 한다면 Hash 함수 사용을 고려해보세요.

식별 가능성: 사람이 읽을 수 있는 디자인

클라이언트 키 예시 UI

이 값은 토스페이먼츠에서 사용하고 있는 키 값이에요. 이 값을 보면 어떤 생각이 드시나요? 값이 _로 구분되어 있네요. 구분된 첫 번째 값을 먼저 볼까요. test가 앞에 붙은 걸로 봐서 테스트용으로 쓸 것 같아요. test 뒤에는 ck 라는 값이 있네요. 위에 보니 클라이언트 키라고 쓰여있는 걸 보아 ‘client key’를 의미하는 것 같죠. 이렇게 토스페이먼츠의 테스트용 클라이언트 키의 줄임말인 걸 유추해 볼 수 있어요. 이렇게 식별 가능성을 고려해서 ID를 디자인하니 랜덤한 문자열인 D5GePWvyJnrK0W0k6q8gLzN97Eoq만 있는 것보다 개발자가 얻을 수 있는 정보가 훨씬 많아요.

이렇게 객체 ID에 접두사를 붙이면 어떤 장점이 있을까요? 먼저 객체 ID의 가독성이 향상돼요. 객체 ID에 의미 있는 접두사를 사용하면 다른 사람이나 개발자가 객체를 식별하고 이해하기 쉬워지죠. 또 객체들을 접두사로 그룹화하면 특정 유형이나 카테고리에 속한 객체를 쉽게 필터링하거나 검색할 수 있어요. 예를 들어, user- 접두사를 가진 모든 사용자 객체를 조회하거나 prod- 접두사를 가진 제품 객체들을 필터링할 수 있죠. 마지막으로 접두사는 객체 ID 충돌을 방지하는 데 도움을 줄 수 있습니다. 서로 다른 유형의 객체에 다른 접두사를 사용하면 객체 ID가 충돌할 가능성이 줄어들기 때문이에요.

이렇게 객체 ID를 생성하고 관리하는 규칙을 설정하고 적용하면 사람이 읽기 좋을 뿐 아니라, 데이터의 예측 가능성과 일관성도 같이 높아져요. 객체 ID는 데이터 간의 관계를 정의하는 데 사용되기 때문이죠.

Customer - Order 객체 예시 UML

예를 들어 볼게요. 사용자를 나타내는 Customer 객체와 주문을 나타내는 Order 객체 사이에는 강한 연관성이 있어요. 그래서 Order 객체는 주문한 특정 사용자를 식별하기 위한 사용자 ID, 즉 Customer 객체의 ID를 포함해요. 이 값으로 특정 사용자의 주문 목록을 쉽게 추적하고, 사용자가 주문한 상품, 결제 정보 등과 연관된 정보를 쉽게 얻을 수 있겠죠. 이렇게 객체 ID만 잘 디자인해도 특정 객체가 다른 객체와 어떻게 연관되어 있는지를 이해하기가 쉬워져요.

예제: 고객 키 만들기

토스페이먼츠를 사용하다 보면 API나 SDK 요청을 보낼 때 가맹점에서 직접 객체 ID를 만들어서 보내야 하는 경우가 있어요. 여기서는 결제위젯을 초기화할 때 사용하는 customerKey를 예시로 살펴볼게요. customerKey는 고객을 특정하는 값으로 가맹점의 고객 정보와 연동된 고유한 값으로 가맹점에서 직접 만들어서 넣어줘야 하는 값입니다. 아래와 같이 결제위젯을 초기화할 때 사용합니다.

<head>
  <meta charset="utf-8" />
  <!-- 결제위젯 SDK 추가 -->
  <script src="https://js.tosspayments.com/v1/payment-widget"></script>
</head>
<body>
  <div id="payment-method"></div>
  <button id="payment-button">결제하기</button>
  <script>
    const clientKey = "test_ck_D5GePWvyJnrK0W0k6q8gLzN97Eoq"
    const customerKey = "IA7nOXP2MU3-drFYh0bQR" // 내 상점에서 고객을 구분하기 위해 발급한 고객의 고유 ID
    const button = document.getElementById("payment-button")
		// ...
	</script>
</body>

이 값을 만약 user-01 같은 형식으로 사용하면 어떻게 될까요? 만약 하나의 customerKey만 유출되어도 누구나 다른 값을 유추해서 악의적으로 사용할 수 있을 거예요. 그래서 연동문서에서 UUID와 같이 충분히 무작위적인 값을 사용해 달라고 안내하고 있어요.

정리하면, 객체 ID는 고유성, 식별 가능성, 보안성을 충분히 만족해야 합니다. 고유성과 보안성은 기본이고, 식별 가능성까지 고려해 사람이 읽을 수 있고 이해할 수 있는 객체 ID를 만들어 보세요. 효율적인 ID 시스템은 데이터를 빠르게 검색하고 참조할 수 있게 함으로써 전반적인 API의 성능 향상에 기여합니다.

📍 참고하면 좋은 자료

토스페이먼츠 Twitter를 팔로우하시면 더욱 빠르게 블로그 업데이트 소식을 만나보실 수 있어요.


profile
개발자들이 만든, 개발자들을 위한 PG사 토스페이먼츠입니다.

0개의 댓글