본문 바로가기
C.W.K.
Stream
Lesson 03 of 05 · published

단서는 페이로드에 넣어

~12 min · api-design, payload, disclosure, read-model

Level 0원석
0 XP0/36 lessons0/12 achievements
0/100 XP to next level100 XP to go0% complete
문서에 적은 단서는 독자 한 명한테 닿는다. 페이로드에 실은 단서는 모든 소비자한테, 영원히 닿는다.

공개를 놓을 수 있는 네 자리

창을 밝혀야 한다는 데는 다들 동의해. 어디 놓냐가 진짜 결정이고, 선택지들이 동등하지 않아.

문서에. 공짜고, 단서가 필요한 그 순간에 문서를 읽는 사람한테만 닿아. 실제로는 그거 쓴 사람이지.

프론트엔드 컴포넌트에. 낫지. 독자가 보니까. 근데 컴포넌트 하나에 살아. 커맨드라인은 그게 없어. 그 숫자를 인용하는 위임 지시서도 없고. 다음에 누가 만들 표면도 없고, 있어야 했다는 것도 몰라.

소비자마다 필요할 때 계산. 이제 소비자마다 기간을 알아내려고 역사 전체가 필요해지고, 그건 소비자마다 같은 쿼리를 다시 구현한다는 뜻이고, 그중 하나는 미묘하게 틀리게 짜.

행에. 읽기 모델이 한 번 계산하고, 그 행의 모든 소비자가 — 모든 표면, 모든 내보내기, 모든 지시서, 아무도 아직 생각 못 한 미래의 모든 연동이 — 요청하든 말든 그걸 받아.

공개는 문서가 아니라 데이터랑 같이 다녀. 어떤 숫자가 단서 없이 해석이 안 되면, 그 단서는 숫자의 일부고 같은 페이로드에 속해. 다른 배치는 전부 미래의 모든 소비자가 알아서 그 단서를 발견할 거라는 데 거는 내기고, 그 내기는 아무도 안 알려준 첫 연동에서 져.

행이 실제로 뭘 들고 다니냐

읽기 모델 행마다 값이랑 데이터 날짜, 백분위, 뒤에 받치는 표본 개수, 역사가 시작하는 날짜, 그리고 연 단위 기간을 들고 있어. 중요한 의미에서 선택적인 건 하나도 없어. 하나라도 빼면 나머지가 알려진 것보다 더 세게 주장해.

계열 자기 최솟값이랑 중앙값이랑 최댓값도 실어. 조용히 일을 하거든. 백분위는 순위를 알려주고, 분포는 모양을 알려줘. 살아 있는 CAPE 행이 딱 그 예야. 값 43.19, 백분위 99.7, 역사 중앙값 16.61, 역사 최댓값 44.20. 순위는 꼭대기 근처라고 말해. 중앙값은 평소 값의 두 배 반쯤이라고 말하고. 최댓값은 그리고 역대 최고에서 그리 멀지 않다고 말해. 순위 혼자서는 그중 아무것도 표현 못 해.

쓸 때가 아니라 읽을 때 계산

이걸 감당 가능하게 만드는 구조적 요점 하나. 백분위랑 창은 스냅샷 옆에 저장하는 게 아니라 추가 전용 계열에서 읽을 때 계산돼.

이게 맞는 방향이고, 저장 용량 때문만은 아니야. 백분위는 관측의 성질이 아니야. 지금까지 알려진 나머지 전부에 대한 관측의 성질이고, 그건 새 행이 올 때마다 바뀌어. 쓸 때 저장하면 아직 움직이고 있는 관계를 얼려버리는 거고, 계산된 그날에는 참이었던 백분위로 가득한 테이블을 얻게 돼. 읽을 때 유도하면 답이 항상 현재 역사에 대한 거고, 그게 사람들이 실제로 던지는 유일한 판본의 질문이야.

비용은 진짜고, 재봤어. 요청마다 계열 전체를 다시 계산하는 게 공짜는 아니고, 답은 미리 계산해두는 게 아니었어. 엔진 쓰기 카운터에 캐시를 거는 거였지. 엔진이 유일한 기록자니까 쓰기를 세는 게 싸고 하나도 안 놓쳐. 캐시된 읽기 모델은 쓰기가 시도됐을 때 다시 지어지고, 그 밖에는 안 지어져. 수동 새로고침은 여전히 즉시 보이고, 조용한 대시보드는 페이지 로드마다 수만 행을 다시 짓는 짓을 멈춰.

Code

서빙되는 게이지 행 하나 — 숫자, 그리고 그걸 읽는 데 필요한 전부·json
{
  "gauge": "cape",
  "market": "us",
  "series": "SHILLER",
  "value": 43.1884,
  "data_date": "2026-08-06",
  "fetched_at": "2026-08-07T22:11:13.840312+00:00",

  "percentile": 99.7,
  "points": 1748,
  "first_date": "1881-01-01",
  "window_years": 145.6,
  "hist_min": 4.7842,
  "hist_median": 16.6063,
  "hist_max": 44.1979,

  "source": "derived:shiller-ext P_real/E10trend(4%yr real, cal 2026-02)"
}

// Seven context fields for one value. The CLI gets them. The
// dashboard gets them. A delegation brief quoting this row gets
// them. Nobody has to know to ask.
//
// Note the source string: it names the EXTENSION method and its
// assumption, because months past the sheet's freeze are estimates.
// A number that was estimated says so where it is stored.

External links

Exercise

네 시스템에서 단서가 필요한 숫자를 돌려주는 API 응답을 하나 찾아봐. 기간을 안 밝힌 비율, 모집단을 안 밝힌 평균, 임계값을 안 밝히고 계산된 상태값. 그 한정 필드를 페이로드에 추가하고, 소비자들을 grep 해서 그거 없이 그 숫자를 표시하던 데가 몇 개인지 세봐. 보통 예상보다 많아. 소비자 하나하나가 그때 머릿속에 단서를 들고 있던 사람 손에 쓰였거든.
Hint
좋은 테스트: 응답 스키마만 읽은 새 소비자가 다른 지식 없이 이 숫자를 제대로 그릴 수 있나? 못 하면 스키마 명세가 부족한 거고, 오늘 맞게 그리는 소비자들은 누가 짰냐의 우연으로 맞는 거야.

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고

댓글 0

🔔 답글 알림 (로그인 필요)
로그인댓글을 남기려면 로그인해 주세요.

아직 댓글이 없어요. 첫 댓글을 남겨보세요.