fix: 하네스 제거 및 keycloak 문서 보강
This commit is contained in:
@@ -1 +0,0 @@
|
||||
../../vault/20-evidence/official-docs/schema-protobuf-vs-json-evolution.md
|
||||
@@ -0,0 +1,106 @@
|
||||
---
|
||||
title: Protocol Buffers proto3 schema evolution rules
|
||||
source_type: official-doc
|
||||
url: https://protobuf.dev/programming-guides/proto3/
|
||||
archive_url:
|
||||
status: raw
|
||||
confidence: high
|
||||
tags: [ca-tmpl, schema, serialization, protobuf, schema-evolution, json]
|
||||
related_projects: [ca-tmpl]
|
||||
related_branches: [feature-schema-serialization-contract, feature-api-compatibility-deprecation-contract]
|
||||
created: 2026-05-22
|
||||
last_reviewed: 2026-05-27
|
||||
---
|
||||
|
||||
# Protocol Buffers proto3 schema evolution rules
|
||||
|
||||
> Layer: `raw/official-docs/` — Protobuf 공식 proto3 guide 의 "Updating A Message Type" 섹션 verbatim 발췌. ca-tmpl 의 `unknown field strict inbound / tolerant outbound` 결정과의 비교 + JSON 환경에서 흉내내야 할 안전성 식별.
|
||||
|
||||
## Parent / 활용 branch (필수)
|
||||
|
||||
| Branch | 이 자료가 정당화하는 결정 |
|
||||
|---|---|
|
||||
| [[raw/branch-notes/feature-schema-serialization-contract]] | G-F 대안 2 (Protobuf strict typing + reserved field) 의 1차 근거 — Protobuf 의 wire-format 강제와 ca-tmpl JSON 의 OpenAPI drift 검증을 비교 |
|
||||
| [[raw/branch-notes/feature-api-compatibility-deprecation-contract]] | Protobuf 의 "removed field 재사용 차단" + "field rename = JSON encoding 위험" 두 사실이 ca-tmpl 의 deprecation catalog / rename = breaking 결정의 외부 근거 |
|
||||
|
||||
## 컨텍스트
|
||||
|
||||
ca-tmpl 은 JSON over HTTP 기준이지만, schema evolution 을 **typed schema** (Protobuf/Avro) 와 비교해야 trade-off 가 보임. Protobuf 는 wire-format 안전성을 field number 와 reserved 로 강제. ca-tmpl 결정 (`request fail-fast`, `response strict schema`) 이 이에 비해 무엇을 잃고 얻는지 평가.
|
||||
|
||||
## 출처 / Source
|
||||
|
||||
- 원본 URL: https://protobuf.dev/programming-guides/proto3/
|
||||
- 아카이브 URL: (미수집)
|
||||
- 저자 / 조직: Google / Protocol Buffers project
|
||||
- 발행일: continuously updated
|
||||
- 마지막 확인일: 2026-05-27
|
||||
|
||||
## 핵심 인용 / Key quotes (verbatim)
|
||||
|
||||
> [§Updating A Message Type — Adding] "Adding new fields is safe. If you add new fields, any messages serialized by code using your 'old' message format can still be parsed by your new generated code."
|
||||
|
||||
> [§Updating A Message Type — Removing] "Removing fields is safe. The same field number must not used again in your updated message type. You may want to rename the field instead, perhaps adding the prefix 'OBSOLETE_', or make the field number reserved."
|
||||
|
||||
> [§Reserved fields] "you **must** reserve the deleted field number. If you do not reserve the field number, it is possible for a developer to reuse that number in the future."
|
||||
|
||||
> [§Reserved fields — Risks of reuse] "Reusing a field number makes decoding wire-format messages ambiguous." Identified risks include "Developer time lost to debugging", "A parse/merge error (best case scenario)", "Leaked PII/SPII", "Data corruption".
|
||||
|
||||
> [§Reserved fields — name reuse] "Reusing an old field name later is generally safe, except when using TextProto or JSON encodings where the field name is serialized."
|
||||
|
||||
## Claims Extracted / 추출된 주장
|
||||
|
||||
| Claim ID | Claim (이 자료가 직접 말하는 것) | Evidence quote | Strength | Applies to | Does not prove |
|
||||
|---|---|---|---|---|---|
|
||||
| SPVJ-C1 | proto3 에서 새 field 추가는 안전 — 이전 message format 으로 직렬화된 메시지를 새 코드가 그대로 파싱 가능 (forward compatibility 보장) | [§Updating A Message Type] "Adding new fields is safe. If you add new fields, any messages serialized by code using your 'old' message format can still be parsed by your new generated code." | `official-standard` | proto3 wire-format 의 forward compatibility | 추가된 field 가 모든 코드 경로에서 자동으로 채워진다는 뜻 아님 — default 값 / unset 구분은 별도 시맨틱 |
|
||||
| SPVJ-C2 | field 제거는 안전하나 **동일 field number 를 재사용해서는 안 됨** — rename ("OBSOLETE_" prefix) 또는 reserved 처리 권장 | [§Updating A Message Type] "Removing fields is safe. The same field number must not used again in your updated message type. You may want to rename the field instead, perhaps adding the prefix 'OBSOLETE_', or make the field number reserved." | `official-standard` | proto3 schema 변경 시 field number 정책 | OpenAPI / JSON 환경에서 동일 강제가 표준으로 존재한다는 뜻 아님 — JSON 환경에는 등가 메커니즘 부재 |
|
||||
| SPVJ-C3 | 삭제된 field number 는 **반드시** reserved 처리 필요 — 안 하면 미래 개발자가 그 번호를 재사용 가능 (컴파일러 차단 없음) | [§Reserved fields] "you must reserve the deleted field number. If you do not reserve the field number, it is possible for a developer to reuse that number in the future." | `official-standard` | proto3 schema 변경 / Protobuf 컴파일러 동작 | reserved 처리가 자동으로 일어난다는 뜻 아님 — 개발자가 명시적으로 `.proto` 에 작성해야 함 |
|
||||
| SPVJ-C4 | field number 재사용은 wire-format 디코딩을 ambiguous 하게 만들며, 결과로 (a) 디버깅 시간 손실, (b) parse/merge 에러 (best case), (c) PII/SPII 누출, (d) 데이터 손상 가능 | [§Reserved fields — Risks] "Reusing a field number makes decoding wire-format messages ambiguous." + risk list quoted | `official-standard` | proto3 wire-format 의 호환성 위험 | 위 4가지 위험이 반드시 모두 발생한다는 뜻 아님 — 시나리오별 발생 (best case = parse error) |
|
||||
| SPVJ-C5 | field name 재사용은 일반적으로 안전하나 **TextProto 또는 JSON encoding 사용 시는 위험** — 그 인코딩에서는 field name 이 직렬화됨 | [§Reserved fields] "Reusing an old field name later is generally safe, except when using TextProto or JSON encodings where the field name is serialized." | `official-standard` | proto3 + JSON / TextProto encoding 시 field name 정책 | binary wire-format 환경에서 field name 이 완전 무의미하다는 뜻 아님 — 디버깅 / 로깅에서 사용됨 |
|
||||
|
||||
## Usage Boundaries / 적용 경계
|
||||
|
||||
- **이 자료가 직접 증명하는 것**:
|
||||
- `SPVJ-C1` ~ `C5`: proto3 schema evolution 의 5가지 핵심 규칙 (add 안전, remove + reserved 의무, 재사용 위험, name 재사용 시 JSON 환경 위험)
|
||||
- **이 자료가 증명하지 않는 것**:
|
||||
- OpenAPI / JSON Schema 에 등가 `reserved` 키워드가 존재한다 (별도 page `protobuf-reserved-vs-json-openapi-extension.md` 에서 부재 확인)
|
||||
- Protobuf JSON Mapping 사용 시 자동으로 field name 재사용을 컴파일러가 차단한다는 사실 (proto3 컴파일러는 reserved 키워드 기준으로만 차단)
|
||||
- Protobuf 의 enum 추가가 모든 클라이언트에서 안전하다는 사실 — 본 page 추출 범위 밖
|
||||
- "int32 ↔ int64" 등 wire-호환 type 변경의 정확한 안전 조건 — 별도 섹션
|
||||
- **내 프로젝트에 적용하려면 추가 확인이 필요한 것**:
|
||||
- ca-tmpl 이 JSON 환경에서 Protobuf `reserved` 시맨틱을 OpenAPI `x-` extension 으로 흉내낼 때의 lint tool 선택 ([[raw/official-docs/protobuf-reserved-vs-json-openapi-extension]] 후속 결정)
|
||||
- Protobuf 채택 시 외부 client 의 디코더 의존성 / 디버깅 비용
|
||||
- REST → Protobuf 전환 시 OpenAPI 도구 체인 (Swagger UI, Postman) 의 호환성
|
||||
|
||||
## 메모 / Notes (내 프로젝트 해석)
|
||||
|
||||
> 본 섹션은 자료 직접 인용 아님. ca-tmpl 결정 컨텍스트 해석.
|
||||
|
||||
- Protobuf vs JSON (ca-tmpl) 차이:
|
||||
|
||||
| 측면 | Protobuf | JSON (ca-tmpl) |
|
||||
|---|---|---|
|
||||
| 식별자 | field number (wire 영구) | field name (string) |
|
||||
| unknown field | 디코더가 자동 보존 (by default) | request fail-fast / response forbidden (ca-tmpl) |
|
||||
| 제거 후 재사용 | reserved 로 차단 강제 | OpenAPI 에 명시 안 하면 차단 안 됨 |
|
||||
| 타입 변경 | 일부 wire-호환 변경 허용 (int32 ↔ int64 등) | breaking (ca-tmpl catalog) |
|
||||
| enum 추가 | 안전 | response 는 broken client 가능 |
|
||||
|
||||
- ca-tmpl 이 JSON 에서 Protobuf 의 안전성을 흉내 내려면:
|
||||
- **재사용 차단**: removed field 이름을 OpenAPI 에서 `x-reserved` 같은 확장 또는 별도 catalog 로 강제. CI 에서 같은 이름 재사용을 막아야 함.
|
||||
- **enum 보존**: ca-tmpl 이 채택한 "request unknown enum -> validation failure" 는 Protobuf 의 default 와 반대. 정합성을 위해 compatibility adapter 가 필수 (현재 결정 사항).
|
||||
- **field renaming**: Protobuf 는 JSON 인코딩 사용 시 위험. ca-tmpl 결정 (rename 은 breaking, deprecate first) 과 일치.
|
||||
- Trade-off:
|
||||
- Protobuf 채택: wire format 강제, IDL 기반 codegen, 자동 호환성. 단 디버깅·로그 가독성 ↓, 외부 노출 API 에는 부담.
|
||||
- JSON 유지: 가독성·디버깅·외부 통합 용이. 단 ca-tmpl 처럼 OpenAPI diff + breaking change catalog + strict 정책을 **모두** 갖춰야 동급 안전성에 근접.
|
||||
- 결론: ca-tmpl 이 JSON 기반이라면 Protobuf 의 `reserved` 개념 (이름·필드 재사용 차단) 을 OpenAPI 에 도입하는 것이 가장 큰 보강 포인트.
|
||||
|
||||
## Related / 관련
|
||||
|
||||
- 같은 주제 다른 official-doc:
|
||||
- [[raw/official-docs/protobuf-reserved-vs-json-openapi-extension]] (Protobuf reserved 의 JSON 환경 흉내 보강)
|
||||
- [[raw/official-docs/schema-avro-evolution-rules]] (Avro 측 동일 주제)
|
||||
- [[raw/official-docs/schema-jackson-unknown-field-handling]] (Jackson 측 unknown field)
|
||||
- 인용하는 branch:
|
||||
- [[raw/branch-notes/feature-schema-serialization-contract]] (G-F 대안 2)
|
||||
- [[raw/branch-notes/feature-api-compatibility-deprecation-contract]]
|
||||
- 인용하는 wiki: (미작성)
|
||||
Reference in New Issue
Block a user