Files
llm-wiki/raw/official-docs/protobuf-reserved-vs-json-openapi-extension.md

146 lines
13 KiB
Markdown

---
title: Protobuf reserved Semantics vs JSON/OpenAPI Equivalents
source_type: official-doc
url: https://protobuf.dev/programming-guides/proto3/#reserved
archive_url:
status: needs-confirmation
confidence: medium
tags: [ca-tmpl, ca-schema, protobuf, openapi, json-schema, reserved-fields]
related_projects: [ca-tmpl]
related_branches: [feature-schema-serialization-contract, feature-api-compatibility-deprecation-contract]
created: 2026-05-22
last_reviewed: 2026-05-27
---
# Protobuf reserved Semantics vs JSON/OpenAPI Equivalents
> Layer: `raw/official-docs/` — Protobuf `reserved` 키워드 verbatim + OpenAPI 3.1 / JSON Schema 의 등가 시맨틱 부재 비교. ca-tmpl (JSON 기반) 이 schema 호환성을 강제하려면 무엇을 자체적으로 정의해야 하는지 평가하기 위한 보강 자료.
## Parent / 활용 branch (필수)
| Branch | 이 자료가 정당화하는 결정 |
|---|---|
| [[raw/branch-notes/feature-schema-serialization-contract]] | G-F follow-up — JSON 환경에서 Protobuf `reserved` 시맨틱 흉내 메커니즘 (OpenAPI `x-` extension vs 별도 markdown catalog vs JSON Schema `deprecated`) 비교 근거 |
| [[raw/branch-notes/feature-api-compatibility-deprecation-contract]] | "removed field name 재사용 차단" 정책의 표준 도구 부재 사실 — 자체 lint / code review 강제 결정의 1차 근거 |
## 컨텍스트 / 왜 저장했는지
Protobuf 의 `reserved` 키워드는 schema 호환성의 핵심 장치 — field number / name 재사용을 **컴파일러 단계에서 영구 차단**한다. ca-tmpl 은 JSON over HTTP 기반이라 `reserved` 를 직접 흉내낼 수 없고, OpenAPI / JSON Schema 에는 등가 시맨틱이 부재. G-F ([[raw/branch-notes/feature-schema-serialization-contract]]) 외부 근거 조사에서 "Protobuf `reserved` 가 JSON 환경에서 ca-tmpl 이 가장 크게 보강할 부분" 으로 식별됐으나, **어떤 메커니즘으로** 보강할지 (OpenAPI `x-` extension / 자체 markdown catalog / lint tool) 는 미정. 본 raw 는 후속 결정을 위한 시맨틱 비교 근거.
## 출처 / Source
- 원본 URL: https://protobuf.dev/programming-guides/proto3/#reserved
- 보조 URL:
- https://spec.openapis.org/oas/v3.1.0 (OpenAPI 3.1 spec — `deprecated` 키워드와 Specification Extensions)
- https://json-schema.org/draft/2020-12/json-schema-validation (JSON Schema `deprecated` keyword)
- https://docs.stripe.com/upgrades (Stripe API: removed field 처리)
- https://docs.github.com/en/rest/overview/api-versions (GitHub REST: removed field 처리)
- 아카이브 URL: (미수집)
- 저자 / 조직: Google / Protocol Buffers project; OpenAPI Initiative (Linux Foundation); JSON Schema org
- 발행일: continuously updated
- 마지막 확인일: 2026-05-27
## 핵심 인용 / Key quotes (verbatim)
### Protobuf 공식 (proto3 guide §Reserved)
> [§Reserved] "If you update a message type by entirely deleting a field, or commenting it out, future developers can reuse the field number when making their own updates to the type."
> [§Reserved] "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 — 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 — name reuse] "Reusing an old field name later is generally safe, except when using TextProto or JSON encodings where the field name is serialized."
### OpenAPI 3.1 / JSON Schema (보조 인용 — 보조 URL 출처)
> [OpenAPI 3.1 §4.9 Specification Extensions, 보조 인용] "Specification Extensions... allow vendor specific extensions. The extensions properties are implemented as patterned fields that are always prefixed by `x-`."
> [JSON Schema 2020-12 §9.3, 보조 인용] "The `deprecated` keyword applies to Schema Objects to indicate that this schema has been deprecated... but does not affect the validation of an instance."
## Claims Extracted / 추출된 주장
| Claim ID | Claim (이 자료가 직접 말하는 것) | Evidence quote | Strength | Applies to | Does not prove |
|---|---|---|---|---|---|
| PRVJ-C1 | message type 에서 field 를 삭제/주석화하면 미래 개발자가 그 field number 를 재사용할 수 있다 (자동 차단 없음) | [§Reserved] "If you update a message type by entirely deleting a field, or commenting it out, future developers can reuse the field number when making their own updates to the type." | `official-standard` | proto3 컴파일러 동작 | 다른 schema 시스템 (Avro / JSON Schema) 에서 동일 위험이 있다는 뜻 아님 — Protobuf 한정 사실 |
| PRVJ-C2 | 삭제된 field number 는 **반드시** reserved 처리 필요 — reserve 안 하면 미래 개발자가 재사용 가능 | [§Reserved] "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 변경 워크플로 | reserved 처리가 lint / pre-commit 으로 자동 추가된다는 뜻 아님 — 개발자 명시 작성 의무 |
| PRVJ-C3 | field number 재사용 시 wire-format 디코딩이 ambiguous — 결과로 (a) 디버깅 시간 손실, (b) parse/merge error (best case), (c) PII/SPII 누출, (d) 데이터 손상 가능 | [§Reserved — Risks] "Reusing a field number makes decoding wire-format messages ambiguous." + risk list | `official-standard` | Protobuf wire-format 호환성 | 위 4가지 위험이 항상 모두 발생한다는 뜻 아님 — 시나리오별 |
| PRVJ-C4 | field name 재사용은 일반적으로 안전하나 **TextProto / JSON encoding 사용 시 위험** — 해당 인코딩에서 field name 이 직렬화되기 때문 | [§Reserved] "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 | binary 환경에서 name 재사용이 완전 자유라는 뜻 아님 — 디버깅 / 로깅 / 코드 가독성 영향 별도 |
| PRVJ-C5 | OpenAPI 3.1 의 Specification Extensions 는 `x-` 접두 vendor-specific 키 허용 (어떤 정책도 정의하지 않음, 단순 확장 허가) | [OpenAPI 3.1 §4.9, 보조 인용] "Specification Extensions... allow vendor specific extensions. The extensions properties are implemented as patterned fields that are always prefixed by `x-`." | `official-standard` | OpenAPI 3.1 spec 확장 메커니즘 | `x-removed-fields` 같은 특정 확장이 표준이라는 뜻 아님 — 자체 lint 룰을 직접 작성해야 함 |
| PRVJ-C6 | JSON Schema 2020-12 의 `deprecated` 키워드는 *비권장* 신호만 제공 — instance validation 에는 영향 없음 (재사용 차단 아님) | [JSON Schema 2020-12 §9.3, 보조 인용] "The `deprecated` keyword applies to Schema Objects to indicate that this schema has been deprecated... but does not affect the validation of an instance." | `official-standard` | JSON Schema `deprecated` 의미 | `deprecated: true` 로 Protobuf `reserved` 의 재사용 차단을 흉내낼 수 있다는 뜻 아님 — 시맨틱 다름 |
### 미확인 / 후속 확인 필요
- **Stripe / GitHub 의 removed field name 재사용 정책**: 공개 문서상 명시적 reserved-style 시맨틱 부재. 본 raw 에서는 claim 으로 등록하지 않음 (보조 URL 직접 verbatim 미수집).
## Usage Boundaries / 적용 경계
- **이 자료가 직접 증명하는 것**:
- `PRVJ-C1` ~ `C4`: Protobuf `reserved` 의 정확한 시맨틱과 위험 (proto3 공식)
- `PRVJ-C5` ~ `C6`: OpenAPI 3.1 `x-` extension 메커니즘 존재 + JSON Schema `deprecated` 의 validation 비영향 (보조 인용)
- **이 자료가 증명하지 않는 것**:
- JSON 환경에서 Protobuf `reserved` 와 1:1 등가인 표준 메커니즘이 **존재한다** (오히려 부재 확인)
- `x-removed-fields` 같은 특정 OpenAPI 확장이 공식 권장이라는 사실 (vendor-specific extension)
- Stripe / GitHub 가 removed field name 재사용을 공식 정책으로 명시한다는 사실 (운영 정책으로 회피 추정)
- **내 프로젝트에 적용하려면 추가 확인이 필요한 것**:
- ca-tmpl 이 채택할 lint tool (Spectral / Redocly CLI 등) 의 custom rule 작성 가능 여부
- 별도 markdown catalog (`docs/removed-fields-catalog.md`) 와 OpenAPI diff 의 sync 자동화 방안
- JSON Schema `deprecated` + OpenAPI `x-` extension 조합의 실무 운영 사례 (현재 부재)
## 메모 / Notes (내 프로젝트 해석)
> 본 섹션은 자료 직접 인용 아님. ca-tmpl 결정 컨텍스트 해석.
### Protobuf `reserved` vs JSON/OpenAPI 환경 비교
| 측면 | Protobuf `reserved` | OpenAPI 3.1 / JSON Schema |
|---|---|---|
| 식별자 | field number (int) + field name (string) | property name (string) |
| 재사용 차단 강제 | 컴파일러가 거부 (`.proto` 빌드 실패) | **등가 없음**`deprecated: true` 는 표시만, 재사용 차단 아님 |
| 표현 방식 | `reserved 3, 5;` / `reserved "foo", "bar";` | (없음) → `x-removed-fields` 등 자체 extension 필요 |
| 위반 시 효과 | wire format ambiguity, PII leak, parse error | 명시적 차단 없으면 typo 또는 의도적 재사용으로 의미 충돌 가능 |
| 도구 지원 | protoc 빌드 단계 | 별도 lint / OpenAPI diff 도구 필요 (표준 부재) |
### JSON 환경에서의 흉내 대안
1. **OpenAPI Specification Extension (`x-removed-fields`)**:
- OpenAPI 3.1 §4.9 가 `x-` 접두 vendor extension 을 허용. schema object 에 `x-removed-fields: ["legacyAmount", "obsoleteFlag"]` 같은 배열을 두고 CI 에서 이 목록과 신규 추가 field 이름이 겹치면 빌드 실패시키는 방식.
- 장점: schema SSOT (OpenAPI) 내부에 catalog 가 있어 표류 위험 ↓.
- 단점: `x-` extension 은 vendor-specific 이라 **표준 검증 도구 부재** — 자체 lint 룰을 직접 작성해야 한다.
2. **JSON Schema `deprecated` keyword**:
- JSON Schema 2020-12 와 OpenAPI 3.1 이 함께 정의하는 표준 키워드. `deprecated: true`*지금 사용 비권장* 신호일 뿐 **재사용 차단이 아니다**.
- field 가 완전히 사라진 뒤에는 schema 에서도 사라지므로 `deprecated` 만으로는 미래 재사용 방지가 불가.
- 결론: deprecation marker 로는 적합, reserved 시맨틱 흉내로는 **부적합**.
3. **자체 markdown / YAML catalog**:
- 별도 파일 (예: `docs/removed-fields-catalog.md`) 에 제거된 field name / 번호 / 제거 일자 / 사유를 기록하고, code review 나 CI 에서 신규 OpenAPI diff 와 cross-check.
- 장점: tool 에 종속되지 않음, 사람이 읽기 쉬움.
- 단점: schema 와 catalog 가 별도라 sync 실패 위험. 자동화하려면 결국 lint script 가 필요.
4. **GitHub / Stripe API 의 실제 처리** (보조 — 본 자료가 단정하지 않음):
- **Stripe**: account 단위 version pin + freeze forever 정책으로 *제거* 보다는 *구버전 영구 응답* 을 택해 재사용 문제를 회피.
- **GitHub REST**: 24개월 EOL + `410 Gone` 응답. EOL 된 version 에서 제거된 field 이름의 신규 재사용 정책은 공개 문서상 명시되지 않음 (공식 reserved-style 시맨틱 부재).
- 결론: 공개 API 사례에서도 **field name 재사용 차단의 명시적 표준은 없다**. 진영별로 운영 정책으로 회피하는 형태.
### Trade-off
- **OpenAPI `x-` extension 채택**: schema SSOT 에 catalog 가 통합되어 표류 ↓. 단 표준 검증 도구가 없어 자체 lint 필수, 도구 채택 자체가 코드 단계 결정.
- **자체 markdown catalog**: 가독성 ↑, tool-free. 단 schema 와 별도라 sync 실패 위험, code review 에 의존.
- **JSON Schema `deprecated` 단독**: deprecation marker 로만 적합, reserved 시맨틱 흉내 **불가**.
### 결론
Protobuf `reserved` 의 wire-format 수준 강제력을 JSON 환경에서 1:1 흉내내는 표준 메커니즘은 **존재하지 않는다.** ca-tmpl 이 채택할 수 있는 현실적 옵션은 (a) OpenAPI `x-removed-fields` extension + 자체 lint, (b) 별도 markdown catalog + code review/CI, 두 가지. 둘 다 도구 선택이 따라오므로 코드 단계 (Phase C2 이후) 결정 사항.
## Related / 관련
- 같은 주제 다른 official-doc:
- [[raw/official-docs/schema-protobuf-vs-json-evolution]] (선행 source — Protobuf 측 원문 발췌)
- [[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 follow-up)
- [[raw/branch-notes/feature-api-compatibility-deprecation-contract]]
- 인용하는 wiki: (미작성)