Cheondi
개발 · API

테마와 차트 설정을 같이 동기화해도 될까

성격이 다른 설정을 한 API에서 동기화하며 갱신 단위와 충돌 범위를 나눈 기록입니다.

  • #sync
  • #api
  • #data-model

테마 동기화가 동작한 뒤 차트 설정도 같은 데이터에 추가했다. 설정이라는 공통 이름이 있으니 한 객체로 보내는 게 자연스러워 보였다. 그런데 한 기기에서 테마를 바꾸고 다른 기기에서 차트 선 색을 바꾸면 마지막 저장이 상대 변경까지 되돌리는 일이 생겼다.

큰 설정 객체 전체를 매번 덮어쓰는 방식은 구현은 단순했지만 충돌 범위가 너무 넓었다.

함께 바뀌는 단위를 찾았다

테마와 글자 크기는 화면 외형이라는 같은 이유로 바뀌었다. 차트 지표와 표시 옵션은 별도 화면에서 훨씬 자주 수정됐다. 저장 모델을 영역별 문서처럼 나눴다.

{
  "appearance": { "revision": 4, "theme": "dark" },
  "chart": { "revision": 11, "grid": true, "indicators": [] }
}

API가 하나여도 영역별 revision과 변경 필드를 전달하면 관련 없는 설정을 덮지 않을 수 있었다.

부분 업데이트의 의미를 정했다

필드가 없는 것과 값을 비우는 것은 달랐다. null을 삭제로 볼지 변경 없음으로 볼지 서버와 클라이언트가 같은 규칙을 가져야 했다.

public record ChartPatch(
    Optional<bool> Grid,
    Optional<IReadOnlyList<string>> Indicators);

실제 구현 방식은 달라도 “전송 안 함”, “빈 값으로 변경”, “값 설정”을 구분하는 계약이 필요했다.

적용 이벤트도 영역별로 보냈다

설정 하나가 바뀔 때마다 모든 화면을 새로고침하면 차트가 다시 로딩되고 입력 포커스가 사라졌다. 외형 변경과 차트 변경 이벤트를 나누고 필요한 컴포넌트만 반응하게 했다.

동기화 응답을 적용할 때도 로컬에서 수정 중인 영역인지 확인했다. 서버 응답이 늦게 왔다고 현재 편집 값을 조용히 덮지 않았다.

테스트는 테마만 바꾸기, 차트만 바꾸기, 서로 다른 기기에서 동시에 각 영역 바꾸기, 같은 영역을 동시에 바꾸기로 나눴다. 성공 요청만 확인할 때는 보이지 않던 충돌 범위가 이 조합에서 드러났다. 이전 버전 클라이언트가 모르는 새 필드를 보존하는지도 함께 확인했다.

데이터 모델은 협업 방식까지 만들었다

처음에는 JSON을 잘 나누는 정도의 문제라고 생각했다. 실제로는 어느 팀과 화면이 독립적으로 변경할 수 있는지를 데이터 구조가 결정했다. 너무 큰 객체는 코드뿐 아니라 배포와 충돌도 함께 묶었다.

이 경험 뒤 “같은 설정”이라는 이름만으로 한 덩어리로 만들지 않는다. 변경 빈도와 소유 화면, 충돌 시 영향을 보고 동기화 단위를 정한다. 데이터 경계가 작을수록 실패도 관련된 영역 안에 머물렀다.