fix: 하네스 제거 및 keycloak 문서 보강
This commit is contained in:
@@ -1 +0,0 @@
|
||||
../../vault/20-evidence/official-docs/idempotency-no-api-level-github-rest.md
|
||||
@@ -0,0 +1,102 @@
|
||||
---
|
||||
title: No-API-level Idempotency — GitHub REST API 사례 및 패턴
|
||||
source_type: official-doc
|
||||
url: https://docs.github.com/en/rest
|
||||
archive_url:
|
||||
status: raw
|
||||
confidence: medium
|
||||
tags: [ca-idempotency, no-server-dedup, client-retry, github-api, official-doc]
|
||||
related_projects: [ca-skeleton-operational-contract]
|
||||
related_branches: [feature-rate-limit-idempotency-contract, feature-api-contract-baseline]
|
||||
created: 2026-05-22
|
||||
last_reviewed: 2026-05-27
|
||||
---
|
||||
|
||||
# No-API-level Idempotency — GitHub REST API 사례
|
||||
|
||||
> Layer: `raw/official-docs/` — GitHub REST API 공식 문서의 **부재** 를 근거로 사용. ca-tmpl Topic 5 의 대안 5 (no API-level idempotency, client retry 책임만) 의 대표 사례.
|
||||
|
||||
## Parent / 활용 branch (필수)
|
||||
|
||||
| Branch | 이 자료가 정당화하는 결정 |
|
||||
|---|---|
|
||||
| [[raw/branch-notes/feature-rate-limit-idempotency-contract]] | "API-level idempotency 없음" 대안 (대안 5) 의 대표 사례 — ca-tmpl 도메인에서 server-side dedup 채택 결정의 대조군 |
|
||||
| [[raw/branch-notes/feature-api-contract-baseline]] | API contract baseline 에서 Idempotency 정책을 명시할 때 "쓰지 않는 경우" 의 trade-off 비교 |
|
||||
|
||||
## 컨텍스트 / 왜 저장했는지
|
||||
|
||||
ca-tmpl 대안 5번 **"No API-level idempotency — client retry 책임만"**의 대표 사례. 결제/금융이 아닌 일반 REST API가 굳이 server-side dedup을 두지 않을 때의 trade-off 비교용. GitHub 문서는 idempotency key 헤더/필드를 **언급하지 않는 것 자체** 가 근거.
|
||||
|
||||
## 출처 / Source
|
||||
|
||||
- 원본 URL: https://docs.github.com/en/rest (REST API root index)
|
||||
- 아카이브 URL: (미수집)
|
||||
- 저자 / 조직: GitHub Docs
|
||||
- 발행일: rolling docs
|
||||
- 마지막 확인일: 2026-05-27
|
||||
- 보조 참조: RFC 9110 §9.2.2 (HTTP method idempotency semantics)
|
||||
|
||||
## 핵심 인용 / Key quotes (verbatim)
|
||||
|
||||
> [§REST API root index — 2026-05-27 확인] "[index page에 `Idempotency-Key` 헤더 또는 `idempotency_key` 필드에 대한 명시적 spec 없음 — WebFetch 2026-05-27 확인. Rate limits / Best practices / Troubleshooting 하위 문서 링크는 존재하나 idempotency 라는 단어가 표면 카탈로그에 노출되지 않음.]"
|
||||
|
||||
> [§RFC 9110 §9.2.2 — 보조 인용, 본 문서 외부 표준] "A request method is considered 'idempotent' if the intended effect on the server of multiple identical requests with that method is the same as the effect for a single such request."
|
||||
|
||||
> [§GitHub REST API — observed pattern, 본 문서가 직접 다루지 않는 부재 사실] "mutating POST 의 duplicate 방지는 자연 키 unique 제약 (예: 같은 이름의 label 생성 시 422) 또는 client query 후 재처리에 의존."
|
||||
|
||||
## Claims Extracted / 추출된 주장
|
||||
|
||||
| Claim ID | Claim (이 자료가 직접 말하는 것) | Evidence quote | Strength | Applies to | Does not prove |
|
||||
|---|---|---|---|---|---|
|
||||
| IDMP-GH-C1 | GitHub REST API 공식 문서 root index (2026-05-27 확인 시점) 에는 `Idempotency-Key` 헤더 또는 `idempotency_key` body 필드에 대한 공식 spec 이 표면 카탈로그에 노출되지 않음 | [§REST API root index — 2026-05-27 확인] "WebFetch 2026-05-27 확인 — Rate limits / Best practices / Troubleshooting 하위 문서 링크는 존재하나 idempotency 라는 단어가 표면 카탈로그에 노출되지 않음" | `needs-confirmation` | GitHub REST API 공식 문서 표면 — 개별 endpoint 페이지/하위 가이드 정밀 검색 필요 | 모든 GitHub API endpoint 가 idempotent 가 아니라는 뜻은 아님 — GET/PUT/DELETE 는 HTTP 표준상 idempotent. 특정 endpoint 가 내부적으로 dedup 을 한다는 가능성도 부정하지 않음 |
|
||||
| IDMP-GH-C2 | HTTP 표준 (RFC 9110 §9.2.2) 상 idempotent 메서드의 정의는 "동일한 요청을 여러 번 보낸 effect 가 한 번 보낸 effect 와 같은 것" | [§RFC 9110 §9.2.2] "A request method is considered 'idempotent' if the intended effect on the server of multiple identical requests with that method is the same as the effect for a single such request." | `official-standard` | HTTP/1.1+ 모든 구현 | 이 정의가 application-level dedup (예: Stripe Idempotency-Key) 의 의미와 일치한다는 뜻은 아님 — HTTP semantics 는 effect-level, application dedup 은 request-identity-level |
|
||||
| IDMP-GH-C3 | (observed pattern, 본 문서 외 inference) GitHub mutating POST 에서 duplicate 방지는 자연 키 unique 제약에 의존하는 부분이 있음 (예: 같은 이름의 label 생성 시 422 또는 그에 준하는 에러) | [§GitHub REST API — observed pattern] (개별 endpoint 페이지 정밀 inspection 필요 — root index 만으로는 증명 불가) | `needs-confirmation` | label / branch / tag 등 자연 키가 존재하는 리소스 | 모든 mutating POST 에 자연 키 unique 제약이 있다는 뜻은 아님 — 이슈 코멘트, webhook 호출은 중복 생성됨 |
|
||||
|
||||
## Usage Boundaries / 적용 경계
|
||||
|
||||
- **이 자료가 직접 증명하는 것**:
|
||||
- `IDMP-GH-C1`: GitHub REST API root index 표면에 idempotency 헤더 spec 부재 (2026-05-27 시점, root 페이지 한정)
|
||||
- `IDMP-GH-C2`: HTTP 표준의 idempotency 정의 (이는 application-level dedup 과 다른 개념)
|
||||
- **이 자료가 증명하지 않는 것**:
|
||||
- GitHub 의 모든 endpoint 가 dedup 을 하지 않는다는 단정 — 개별 endpoint 가 자연 키 unique 제약을 가질 수 있음
|
||||
- GitHub 가 의도적으로 server-side dedup 을 거부했다는 정책 진술 — 단지 표면 카탈로그에 spec 이 없을 뿐
|
||||
- "no API-level idempotency 가 모든 도메인에서 부적합" 이라는 일반 결론 — 도메인 (조회/멱등 mutation 위주) 에 따라 합리적
|
||||
- **내 프로젝트에 적용하려면 추가 확인이 필요한 것**:
|
||||
- GitHub 의 개별 mutating endpoint 가 어떤 dedup 패턴을 쓰는지 (자연 키 / clientMutationId / 없음) 정밀 inspection
|
||||
- GraphQL `clientMutationId` 의 server 측 dedup 여부 (Relay spec 상으로는 echo 용으로 알려져 있으나 GitHub 의 구현 동작은 별도 확인)
|
||||
- ca-tmpl 의 use case 추상화 layer 가 자연 키 모델과 호환 불가한 이유의 본문 논증
|
||||
|
||||
## 메모 / Notes (내 프로젝트 해석)
|
||||
|
||||
> 본 섹션은 자료 직접 인용 아님. ca-tmpl 결정 컨텍스트 해석.
|
||||
|
||||
- **key scope (어떤 dimension으로):** N/A. 서버가 키를 관리하지 않음.
|
||||
- **TTL:** N/A.
|
||||
- **저장소:** N/A.
|
||||
- **duplicate 처리:**
|
||||
- 자연 키 unique 제약이 있는 경우만 422/409 (예: 동일 이름 라벨 생성).
|
||||
- 그 외(이슈 코멘트, webhook 호출 등)는 그대로 중복 생성됨.
|
||||
- **fingerprint (same key, different body):** N/A.
|
||||
- **장점:**
|
||||
- 서버 구현 단순. 별도 테이블/캐시/lock 불필요.
|
||||
- 표준 HTTP 의미론만으로 충분한 API (조회/멱등 mutation 위주)면 비용 0.
|
||||
- 클라이언트가 retry 정책을 자유롭게 설계 가능.
|
||||
- **단점:**
|
||||
- 결제·잔액·인벤토리처럼 **외부 상태를 변경하는 도메인에선 부적합**. 네트워크 retry로 이중 결제 위험.
|
||||
- 클라이언트가 "성공한 줄 모르고 재시도" 케이스를 막을 방법이 없음.
|
||||
- 책임이 모든 클라이언트로 분산 → 다양한 SDK가 각자 다른 retry/dedup 구현 → 운영 사고 디버깅 어려움.
|
||||
- **ca-tmpl과의 차이:**
|
||||
- 도메인 적합성 결정 차이. ca-tmpl이 use case 단위로 상태 변경을 다룬다면 no-dedup 모델은 위험 회피 불가.
|
||||
- GitHub처럼 "리소스 자연키 + unique 제약"으로 dedup 책임을 모델링하는 대안도 있으나 use case 추상화 layer가 있는 ca-tmpl에는 부적합 (use case는 자연키가 없음).
|
||||
- **결론: ca-tmpl이 server-side dedup을 택한 것은 도메인 특성상 합리적. no-dedup은 ca-tmpl 도메인에서 채택 불가.**
|
||||
|
||||
## Related / 관련
|
||||
|
||||
- 같은 주제 다른 official-doc:
|
||||
- [[raw/official-docs/idempotency-aws-lambda-powertools]] — server-derived key (content hash) 모델
|
||||
- [[raw/official-docs/idempotency-square-api]] — body 필드 방식 (header 아님)
|
||||
- canonical contract 섹션:
|
||||
- [[raw/project-notes/ca-skeleton-operational-contract]] §13. API Contract Surface (Idempotency-Key)
|
||||
- [[raw/project-notes/ca-skeleton-operational-contract]] §18. Control Plane Contract (Rate Limit/Idempotency)
|
||||
- 대안 그룹: **Topic 5 — Idempotency** (대안 5종 + 보조 1종: triple scope / Stripe pair / URL-based / content-hash / no-dedup / + DB vs Redis 저장소)
|
||||
- 본 source의 위치: **대안 5: No API-level idempotency (GitHub)**
|
||||
Reference in New Issue
Block a user