JSON에 텍스트 Diff 사용을 중단하세요: 객체를 비교하는 더 나은 방법
Source: Dev.to
문제: 텍스트 vs. 의미론
표준 diff 알고리즘(예: Myers 차이 알고리즘)은 선형적으로 동작합니다. 문자나 라인의 시퀀스를 비교합니다. 구조를 이해하지 못합니다.
시나리오 A (압축)
압축된 JSON 문자열을 “pretty‑printed” 버전과 비교하면, 데이터가 정확히 동일하더라도 모든 라인이 변경으로 표시됩니다.
시나리오 B (키 순서)
JSON에서 객체의 키 순서는 정의되지 않습니다. 그러나 JSON.stringify()는 순서가 중요한 문자열을 생성합니다. 백엔드 언어(Python, Go 등)가 해시 시드가 무작위화된 맵을 직렬화한다면, JSON 키가 매번 다른 순서로 나올 수 있습니다.
해결책: 의미 기반 비교
이를 해결하려면 문자열을 단순히 비교할 수 없습니다. 객체 자체를 비교해야 합니다.
우리 도구인 Diff Guru는 비교가 시작되기 전에 세 단계를 수행합니다:
- 검증 – 입력 문자열을 파싱해 유효한 JSON인지 확인합니다. 콤마가 빠졌다면 정확한 위치를 알려줍니다.
- 정규화 (깊은 정렬) – 이것이 비밀 소스입니다. 객체를 재귀적으로 순회하면서 모든 키를 알파벳 순으로 정렬합니다.
- 포맷팅 – 정렬된 객체를 일관된 4칸 들여쓰기로 pretty‑print 합니다.
이 단계가 끝난 뒤에 diff 알고리즘을 실행합니다.
로직 (작동 방식)
다음은 { "b": 2, "a": 1 }을 비교 전에 { "a": 1, "b": 2 }로 만들기 위해 사용하는 TypeScript 로직의 간소화된 버전입니다:
const sortDeep = (o: any): any => {
// If it's not an object (or is null), return it as is
if (o === null || typeof o !== 'object') {
return o;
}
// If it's an array, map over the items recursively
// (Note: We usually don't sort arrays, as array order often matters!)
if (Array.isArray(o)) {
return o.map(sortDeep);
}
// It's an object: get keys, sort them, and rebuild the object
return Object.keys(o).sort().reduce((acc: any, key) => {
acc[key] = sortDeep(o[key]);
return acc;
}, {});
};
이 함수를 사용해 데이터를 사전 처리하면 포맷팅과 순서 때문에 발생하는 잡음을 걸러내고, 실제 데이터 변화만 남게 됩니다.
프라이버시 우선 (클라이언트‑사이드 전용)
이 도구를 만들면서 개발자들이 민감한 데이터(API 키, 사용자 레코드, AWS 설정 등)를 diff 도구에 붙여넣는 경우가 많다는 것을 알았습니다.
대부분의 온라인 도구는 데이터를 백엔드로 전송해 diff를 처리합니다. Diff Guru는 그렇지 않습니다.
우리는 100 % 클라이언트‑사이드 아키텍처를 사용합니다. 정렬, 포맷팅, diff 로직(diff‑match‑patch 사용)은 모두 브라우저의 JavaScript 엔진에서 실행됩니다. 페이지를 열고 Wi‑Fi를 끈 상태에서도 도구는 정상적으로 작동합니다. 데이터는 절대 사용자의 머신을 떠나지 않습니다.
직접 사용해 보기
수동으로 누락된 콤마를 찾거나 두 개의 거대한 JSON 블롭이 기술적으로 다른 이유를 찾는 데 지쳤다면, 한 번 사용해 보세요.
👉 JSON Diff & Validator 도구 사용해 보기
무료이며 회원가입이 필요 없고, 데이터 프라이버시를 존중합니다. 사용 후 의견을 댓글로 알려 주세요!