fix: 하네스 제거 및 keycloak 문서 보강

This commit is contained in:
DongHyeonka
2026-07-25 12:53:13 +09:00
parent 6c53ded9cb
commit d71669eb59
2329 changed files with 138239 additions and 172816 deletions
@@ -1 +0,0 @@
../../vault/20-evidence/official-docs/jsonapi-pagination-format.md
@@ -0,0 +1,97 @@
---
title: JSON:API v1.1 — Pagination (page family + links object)
source_type: official-doc
url: https://jsonapi.org/format/#fetching-pagination
archive_url:
status: raw
confidence: high
related_branches: [feature-api-contract-baseline]
related_projects: [ca-skeleton-operational-contract]
tags: [ca-tmpl, api-pagination, jsonapi, page-family, links-object, official-doc]
created: 2026-05-27
last_reviewed: 2026-05-27
---
# JSON:API v1.1 — Pagination (page family + links object)
> Layer: `raw/official-docs/` — JSON:API community 표준 사양 v1.1 의 pagination 절. ca-tmpl API contract baseline D7 (collection pagination 응답 envelope 결정) 의 표준 reference.
## Parent / 활용 branch (필수)
| Branch | 이 자료가 정당화하는 결정 |
|---|---|
| [[raw/branch-notes/feature-api-contract-baseline]] | D7 (collection endpoint 의 pagination envelope — `page` query family + `links.first/last/prev/next` 응답 형태) 결정의 표준 reference |
## 컨텍스트 / 왜 저장했는지
ca-tmpl API contract baseline D7 에서 "왜 `page[number]` / `page[size]` 같은 bracket query 형식인가", "왜 응답에 `links.next` 가 null 일 수 있어야 하는가", "왜 offset 과 cursor 둘 다 받을 수 있는가" 결정의 1차 표준 출처. JSON:API 는 IETF/W3C 표준은 아니지만 community 합의 사양으로 RFC 수준의 normative 강도를 가짐 — RFC 2119 의 MUST/SHOULD/MAY 키워드를 본문에서 직접 사용.
## 출처 / Source
- 원본 URL: https://jsonapi.org/format/#fetching-pagination
- 사양 버전: v1.1
- 아카이브 URL: (미수집)
- 저자 / 조직: JSON:API working group (community spec)
- 발행일: v1.1 published
- 마지막 확인일: 2026-05-27 (WebFetch verbatim 확인)
## 핵심 인용 / Key quotes (verbatim, captured 2026-05-27)
> [§Pagination] "A server **MAY** choose to limit the number of resources returned in a response to a subset (\"page\") of the whole set available."
> [§Pagination] "Pagination links **MUST** appear in the links object that corresponds to a collection."
> [§Pagination] "The following keys **MUST** be used for pagination links: `first`, `last`, `prev`, `next`"
> [§Pagination] "Keys **MUST** either be omitted or have a `null` value to indicate that a particular link is unavailable."
> [§Pagination] "The `page` [query parameter family](#query-parameters-families) is reserved for pagination."
> [§Pagination] "JSON API is agnostic about the pagination strategy used by a server, but the `page` query parameter family can be used regardless of the strategy employed."
## Claims Extracted / 추출된 주장
| Claim ID | Claim (이 자료가 직접 말하는 것) | Evidence quote | Strength | Applies to | Does not prove |
|---|---|---|---|---|---|
| JSONAPI-PAGE-C1 | 서버는 응답에서 전체 set 의 subset ("page") 으로 resource 수를 제한할 수 있음 (`MAY`) | [§Pagination] "A server **MAY** choose to limit the number of resources returned in a response to a subset (\"page\") of the whole set available." | `official-standard` (JSON:API v1.1 community spec) | collection endpoint 가 pagination 을 적용할지 여부 결정 | pagination 이 **의무** 라는 뜻은 아님 — `MAY` 는 옵션 |
| JSONAPI-PAGE-C2 | pagination link 는 collection 에 대응하는 **`links` object 안에** 반드시 나타나야 함 (`MUST`) | [§Pagination] "Pagination links **MUST** appear in the links object that corresponds to a collection." | `official-standard` | 응답 envelope 의 pagination link 위치 결정 (`links` 키 안에) | top-level 에 `links` 외 별도 pagination 메타데이터 (예: `meta.total_count`) 를 둘 수 없다는 뜻은 아님 |
| JSONAPI-PAGE-C3 | pagination link 의 key 는 **`first`, `last`, `prev`, `next`** 4가지여야 함 (`MUST`) | [§Pagination] "The following keys **MUST** be used for pagination links: `first`, `last`, `prev`, `next`" | `official-standard` | pagination link key 명명 결정 | 4개 모두 항상 존재해야 한다는 뜻은 아님 — 다음 claim 참조 |
| JSONAPI-PAGE-C4 | pagination link 가 사용 불가능한 경우 key 를 **omit 하거나 `null` 값** 으로 둬야 함 (`MUST`) | [§Pagination] "Keys **MUST** either be omitted or have a `null` value to indicate that a particular link is unavailable." | `official-standard` | 첫 페이지에서 `prev: null`, 마지막 페이지에서 `next: null` 표현 | 두 방식 중 어느 쪽을 택할지는 서버 자유 — omit vs null 둘 다 valid |
| JSONAPI-PAGE-C5 | `page` query parameter family 는 pagination 전용으로 **reserved** | [§Pagination] "The `page` [query parameter family](#query-parameters-families) is reserved for pagination." | `official-standard` | `page[number]`, `page[size]`, `page[after]` 같은 bracket query 형식 결정 | bracket syntax (예: `page[size]`) 가 의무라는 뜻은 본 인용 범위 밖 — query parameter families 별도 절 위임 |
| JSONAPI-PAGE-C6 | JSON:API 는 pagination **전략 자체에는 agnostic** — offset, cursor, page-based 무엇이든 `page` family 로 표현 가능 | [§Pagination] "JSON API is agnostic about the pagination strategy used by a server, but the `page` query parameter family can be used regardless of the strategy employed." | `official-standard` | ca-tmpl 이 offset-based 또는 cursor-based 둘 다 선택 가능 + 향후 전환 시 query family 유지 가능 | 특정 전략의 성능/일관성 trade-off 는 본 인용 범위 밖 |
## Usage Boundaries / 적용 경계
- **이 자료가 직접 증명하는 것** (2026-05-27 WebFetch verbatim 확인):
- `JSONAPI-PAGE-C1`: pagination 은 `MAY` (옵션)
- `JSONAPI-PAGE-C2`: pagination link 는 `links` object 안에 `MUST`
- `JSONAPI-PAGE-C3`: 4개 key (`first`, `last`, `prev`, `next`) `MUST`
- `JSONAPI-PAGE-C4`: 사용 불가 link 는 omit 또는 null `MUST`
- `JSONAPI-PAGE-C5`: `page` query family reserved
- `JSONAPI-PAGE-C6`: 전략 agnostic
- **이 자료가 증명하지 않는 것**:
- cursor vs offset 중 어느 전략이 더 우수한지 — JSON:API 는 agnostic (`C6`)
- `page[size]` 의 maximum 값 권고 — 본 절 범위 밖
- `total_count` / `total_pages` 같은 meta 정보의 위치 — `meta` object 절 별도
- 응답 status code (200 vs 206 Partial Content) — HTTP RFC 9110 위임
- JSON:API 는 IETF/W3C **공식 표준은 아니지만** community 합의 사양으로 RFC 키워드 (MUST/SHOULD/MAY) 직접 사용 — 본 raw 에서는 `official-standard` 강도로 분류 (정식 IETF 표준과는 다름을 인지)
- **내 프로젝트에 적용하려면 추가 확인이 필요한 것**:
- ca-tmpl 이 JSON:API 전체 envelope (`data`/`included`/`relationships`) 를 채택할지 vs pagination 부분만 차용할지 결정
- Spring HATEOAS 의 `PagedModel` 출력 형식과 JSON:API `links` 형식의 매핑 (둘 다 hypermedia 지만 형태 다름)
- bracket query (`page[size]`) 가 Spring `@RequestParam` 바인딩에서 처리되는 방식 (curly bracket parsing)
## 메모 / Notes
- **RFC 2119 키워드 사용**: 본문이 `MUST` / `MAY` 를 명시적으로 사용 — community spec 이지만 normative 어조.
- **agnostic 전략의 의미**: offset (`page[number]=2&page[size]=20`) 도 cursor (`page[after]=<cursor>&page[size]=20`) 도 같은 `page` family 안에서 표현 가능. ca-tmpl 이 처음 offset 으로 시작하고 나중 cursor 로 전환해도 query family 유지 가능 — backwards compat 관점에서 유리.
- **Spring HATEOAS 와의 차이**: Spring `PagedModel``_links` (HAL 형식), JSON:API 는 `links` (다른 형식). 두 표준은 서로 호환 안 됨 — ca-tmpl 이 둘 중 하나 선택 필요.
## Related / 관련
- 같은 주제 다른 official-doc:
- RFC 5988 / RFC 8288 (Web Linking) — link relation 표준 (별도 raw 작성 후보)
- 인용하는 branch:
- [[raw/branch-notes/feature-api-contract-baseline]]
- 인용하는 project:
- [[raw/project-notes/ca-skeleton-operational-contract]]
- 인용한 wiki 요약: (미작성)