Cheondi
개발 · API

차트 기록 JSON 마이그레이션

차트 히스토리 데이터를 JSON으로 읽고 화면 모델로 바꾸며 데이터 계약을 다듬은 기록입니다.

  • #json
  • #chart
  • #data-contract

차트 기록 데이터를 로컬 JSON으로 받아 표시하는 작업을 했다. 샘플 파일의 배열을 역직렬화해 점을 그리면 될 것 같았다. 작은 데이터는 바로 보였지만 실제 기록을 넣자 일부 구간이 비거나 선이 화면 밖으로 뻗었다. JSON 문법은 정상인데 값의 의미를 잘못 해석하고 있었다.

시간은 초 단위와 밀리초 단위가 섞였고 가격 자릿수도 상품마다 달랐다. 파일을 읽었다는 것과 올바른 차트를 만들었다는 건 다른 성공이었다.

외부 형식과 내부 형식의 분리

JSON 구조를 그대로 차트 컴포넌트에 넘기지 않고 입력 DTO와 내부 포인트를 분리했다.

[Serializable]
public class CandleDto
{
    public long timestamp;
    public string open;
    public string high;
    public string low;
    public string close;
}

public record Candle(DateTimeOffset Time, decimal Open,
    decimal High, decimal Low, decimal Close);

변환 단계에서 시간 단위와 숫자 파싱 규칙을 한 번 적용했다. UI는 정규화된 Candle만 사용했다.

정상 데이터 조건 검증

고가가 저가보다 낮거나 시간이 역순인 값은 그리기 전에 발견해야 했다. 값 하나가 잘못됐다고 전체 파일을 버릴지, 해당 행만 제외할지도 정했다.

bool IsValid(Candle c) =>
    c.Low <= c.Open && c.Open <= c.High &&
    c.Low <= c.Close && c.Close <= c.High;

제외한 행의 개수와 이유는 로그에 남겼고 원본 거래 데이터처럼 민감할 수 있는 값 전문은 출력하지 않았다.

대용량 파일의 스트리밍 처리

전체 JSON을 한 번에 문자열로 만들고 다시 객체 배열로 만들면 같은 데이터가 메모리에 여러 형태로 존재했다. 초기에는 단순한 구현을 유지하되 파일 크기와 파싱 시간을 측정했다. 화면이 멈추는 수준이 되면 청크나 스트리밍 파서를 고려할 기준을 세웠다.

차트에는 필요한 기간만 넘기고 오래된 포인트는 보관 정책에 따라 잘랐다. 성능 문제를 막연히 예상하기보다 데이터 규모를 확인한 뒤 바꿨다.

계약 전달 형식으로서의 JSON

처음에는 JSON이면 플랫폼 사이에서 쉽게 주고받을 수 있다고만 생각했다. 실제 호환성을 만드는 건 필드의 의미, 단위, 누락 가능성, 정렬 순서였다. 문법이 맞아도 계약이 다르면 결과는 틀렸다.

이후 JSON 작업에서는 샘플 하나만 보지 않고 빈 배열, 잘못된 행, 큰 값, 시간 경계를 함께 확인했다. 화면에 선 하나를 그리는 작업이 데이터 계약과 검증을 배우는 계기가 됐다.

기술 문서 기반의 책임 경계

나중에 같은 증상을 다시 만나지 않으려고 문서에 적힌 기준으로 구현을 한 번 더 정리했다.

Unity의 JsonUtility 문서를 다시 읽어 보니, JSON을 자유로운 key-value 저장소처럼 다루기보다 직렬화 가능한 클래스와 필드에 대응시키는 도구라는 점이 더 분명했다. 모르는 필드는 무시되고 빠진 필드는 생성된 객체의 기본값으로 남을 수 있다. 따라서 파싱에 성공했다는 사실과 지금 화면에서 써도 되는 데이터라는 판단은 같지 않다.

RFC 8259도 객체 멤버의 순서를 상호운용 가능한 계약으로 기대하지 않는다. 배열 순서가 의미를 가져도 객체 필드가 적힌 순서까지 로직에 사용하면 다른 생성기나 마이그레이션에서 쉽게 깨진다.

다음에 차트 기록 JSON 마이그레이션 같은 문제를 보면 아래 순서부터 확인하려고 한다.

  • schema version과 마이그레이션 경로
  • 필수 필드·기본값·범위 검증
  • 깨진 항목만 격리하는 단위
  • 이전 버전으로 되돌릴 수 있는지

형식이 올바른 JSON이어도 필수 식별자, 범위, 버전이 맞지 않으면 화면 모델로 넘기지 않는 편이 안전하다.

공식 참고 자료