146 lines
13 KiB
Markdown
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: (미작성)
|