11 KiB
title, source_type, url, archive_url, vendor, related_branches, related_projects, tags, status, confidence, created, last_reviewed
| title | source_type | url | archive_url | vendor | related_branches | related_projects | tags | status | confidence | created | last_reviewed | |||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| official-doc / Google AIP-158 — Pagination | official-doc | https://google.aip.dev/158 |
|
|
|
raw | high | 2026-05-31 | 2026-05-31 |
official-doc / Google AIP-158 — Pagination
Layer:
raw/— 외부 자료(공식 문서)의 원문 발췌·출처 기록. 검증된 요약은/ingest후wiki/concepts/에source-summary-template형식으로 별도 작성. 원본은 raw에 영구 보관.
Parent / 활용 branch
| Branch | 이 자료가 정당화하는 결정 |
|---|---|
| raw/branch-notes/feature-api-contract-baseline | D18 보강: pagination size max cap + 0-indexed page 결정의 normative reference 추가 (JSON:API 는 size cap / index base 에 agnostic — AIP-158 가 server-side cap 을 규범적으로 권고하는 유일한 공식 출처). 또한 D18 의 깊은 offset → cursor 권고와 cursor endpoint 미결정(future B16)의 normative 근거: AIP-158 가 cursor-based pagination (page_token opaque) 의 공식 권고 source. |
출처 / Source
- 원본 URL: https://google.aip.dev/158
- 아카이브 URL: (미등록)
- 저자 / 조직: Google (API Improvement Proposals — googleapis.github.io community)
- 발행일: 2019-02-18 (created); 2019-02-18 (last updated per AIP changelog)
- 마지막 확인일: 2026-05-31
왜 저장했는지 / Why archived
feature-api-contract-baseline D18 의 UNSUPPORTED_DECISION 상태를 해소하기 위해 보관. JSON:API (JSONAPI-PAGE-C1~C6) 는 pagination 전략에 agnostic 이고 size cap 의 normative 진술이 없으나, AIP-158 는 page_size server-side cap ("should coerce down to the maximum permitted page size") 과 page_token 의 opaque-cursor 권고를 normatively 정의한다. 또한 D18 의 cursor 권고(깊은 offset → cursor로 이전)와 향후 cursor endpoint 설계(future B16)의 normative source 역할.
핵심 인용 / Key quotes (verbatim)
[§Guidance / 도입부] "APIs often need to provide collections of data, most commonly in the List standard method. However, collections can often be arbitrarily sized, and also often grow over time, increasing lookup time as well as the size of the responses being sent over the wire. Therefore, it is important that collections be paginated." — line 681–685 in fetched text
[§Guidance / page_size] "The page_size field must not be required. If the user does not specify page_size (or specifies 0), the API chooses an appropriate default, which the API should document. The API must not return an error. If the user specifies page_size greater than the maximum permitted by the API, the API should coerce down to the maximum permitted page size. If the user specifies a negative value for page_size, the API must send an INVALID_ARGUMENT error." — lines 726–733 in fetched text
[§Guidance / page_token] "The page_token field must not be required. If the user changes the page_size in a request for subsequent pages, the service must honor the new page size. The user is expected to keep all other arguments to the RPC the same; if any arguments are different, the API should send an INVALID_ARGUMENT error." — lines 739–744 in fetched text
[§Guidance / next_page_token] "If the end of the collection has been reached, the next_page_token field must be empty. This is the only way to communicate 'end-of-collection' to users. If the end of the collection has not been reached (or if the API can not determine in time), the API must provide a next_page_token." — lines 753–757 in fetched text
[§Opacity] "Page tokens provided by APIs must be opaque (but URL-safe) strings, and must not be user-parseable. This is because if users are able to deconstruct these, they will do so. This effectively makes the implementation details of your API's pagination become part of the API surface, and it becomes impossible to update those details without breaking users." — lines 782–786 in fetched text
Claims Extracted / 추출된 주장
이 자료가 직접 말하는 것만 claim 으로 분리한다. 내 프로젝트에 적용한 결론은 여기 쓰지 않는다.
| Claim ID | Claim (이 자료가 직접 말하는 것) | Evidence quote | Strength | Applies to | Does not prove |
|---|---|---|---|---|---|
| AIP158-C1 | Collections 는 paginated 되어야 하며, pagination 은 처음부터 제공해야 한다 (나중에 추가 시 backward-incompatible) | [§Guidance 도입부] "collections can often be arbitrarily sized [...] Therefore, it is important that collections be paginated." + "RPCs returning collections of data must provide pagination at the outset, as it is a backwards-incompatible change to add pagination to an existing method." | official-reference |
List 메서드를 갖는 모든 API collection | 특정 컬렉션의 크기 threshold 를 정의하지 않음; "arbitrarily sized" 는 서술 |
| AIP158-C2 | page_size 는 required 가 아니어야 하며, API 최대값 초과 시 server 가 최대값으로 cap 적용해야 한다 (SHOULD) |
[§Guidance / page_size] "The page_size field must not be required. [...] If the user specifies page_size greater than the maximum permitted by the API, the API should coerce down to the maximum permitted page size." | official-reference |
page_size request field 를 노출하는 모든 List 메서드 |
최대값의 구체적인 숫자(예: 100, 1000)를 normative 하게 지정하지 않음 — server-defined; cap 이 SHOULD 이므로 강제 아님 (coerce vs reject 선택) |
| AIP158-C3 | page_token 은 required 가 아니어야 하며, 이후 page 요청에서 page_size 를 변경하면 service 가 새 page_size 를 honor 해야 한다 (MUST) |
[§Guidance / page_token] "The page_token field must not be required. If the user changes the page_size in a request for subsequent pages, the service must honor the new page size." | official-reference |
cursor-based pagination 을 구현하는 모든 List 메서드 | page_token 의 내부 encoding (base64, JWE 등) 은 normative 영역 밖 |
| AIP158-C4 | 컬렉션 끝에 도달하면 next_page_token 은 empty 여야 하며(MUST), 이것이 end-of-collection 을 표시하는 유일한 방법이다 |
[§Guidance / next_page_token] "If the end of the collection has been reached, the next_page_token field must be empty. This is the only way to communicate 'end-of-collection' to users." | official-reference |
cursor-based pagination 응답의 next_page_token field |
total_size 를 포함할 수 있으나 선택적(may); total 추정값은 별도로 명시적 문서화 권고 |
| AIP158-C5 | page token 은 opaque (URL-safe) string 이어야 하며(MUST), user-parseable 이면 안 된다(MUST NOT); base64 encoding 만으로는 불충분한 obfuscation | [§Opacity] "Page tokens provided by APIs must be opaque (but URL-safe) strings, and must not be user-parseable. [...] Warning: Base-64 encoding an otherwise-transparent page token is not a sufficient obfuscation mechanism." | official-reference |
cursor token 을 외부 클라이언트에 노출하는 모든 paginated API | token 의 구체적인 encoding 방식(proto 직렬화, JWE, HMAC 등)은 normative 하게 지정하지 않음 — implementation 선택 영역 |
Strength 허용값 참고
본 문서의 모든 Claim 은 official-reference 로 분류한다. AIP (API Improvement Proposals) 는 Google 내부 community guideline 으로 IETF/W3C 국제 표준과 다르며 (official-standard 아님), 특정 vendor 의 제품 문서도 아님 (official-vendor-doc 아님). REST API 설계 community 에서 널리 참조되는 공식 reference 문서.
Usage Boundaries / 적용 경계
-
이 자료가 직접 증명하는 것:
AIP158-C1: pagination 은 List 메서드에 처음부터 제공해야 하며 나중에 추가 시 backward-incompatible changeAIP158-C2:page_sizeserver-side cap 이 Google 공식 guideline 에서 권고되는 표준 패턴임 (should coerce down)AIP158-C3: cursor-based pagination 에서page_token은 optional (MUST NOT be required)AIP158-C4:next_page_tokenempty = end-of-collection 의 유일한 공식 시그널AIP158-C5: page token 은 opaque + URL-safe 이어야 하며 base64 만으로 부족함
-
이 자료가 증명하지 않는 것:
- AIP-158 는 Google community guideline (
official-reference) 이며 IETF/W3C 공식 표준(official-standard) 이 아님 — 모든 REST API 에 법적 구속력이 있는 표준 아님 page_size최대값의 구체적인 숫자 (예: 100, 1000) 는 AIP-158 의 normative 영역 밖 — "server-defined" 라고만 명시.feature-api-contract-baselineD18 의 max=100 은 project-internal trade-off 유지- cursor token 의 구체적인 encoding (proto 직렬화, JWE, HMAC, base64url 등) 은 본 인용 범위 밖 — implementation 선택 영역
- AIP-158 의
page_size/page_token필드명은 protobuf + gRPC 컨텍스트 기반. REST JSON API 에서 동일 필드명 강제는 아님 —feature-api-contract-baseline은page/size파라미터 명칭 사용 (SpringPageable정합) ca-tmpl의 기본 pagination 이 cursor-based 임을 의미하지 않음.feature-api-contract-baselineD7/D18 은 offset-based (page/size) 우선 채택 — 본 raw 는 cursor 대안 정당화 와 향후 cursor endpoint 설계(future B16)의 normative source 역할
- AIP-158 는 Google community guideline (
-
내 프로젝트에 적용하려면 추가 확인이 필요한 것:
page_size > 100요청을 400 VALIDATION_FAILED 로 reject 할지 vs AIP-158 권고처럼 coerce down 할지는 project-internal 결정 (D18 는 400 reject 채택 — UNSUPPORTED_IMPL_DECISION 유지)- cursor endpoint 의 구체적인 token shape (base64url-encoded proto? JWE? HMAC-signed?) 는 future B16 결정 전까지 미정
메모 / Notes
- AIP-158 changelog: "2019-07-19: Update the opacity requirement from 'should' to 'must'." — opaque 요건이 SHOULD 에서 MUST 로 강화된 이력 있음. 현재 normative strength 는 MUST.
- AIP-158 은 protobuf 메시지 포맷으로 예시를 작성하나 §Opacity 와 §Backwards compatibility 의 원칙은 REST JSON API 에도 동일하게 적용 가능.
total_size(int32) field 는 선택적(may) 이며 추정값도 허용 — D18 의meta.page.total과 의미 일치하나 "추정값" 허용 범위는 project 결정 필요.- 추가로 봐야 할 동일 출처 페이지: AIP-132 (List method standard), AIP-160 (Filtering), AIP-159 (Reading across collections).
Related / 관련
- 같은 주제의 다른 official-doc:
- raw/official-docs/jsonapi-pagination-format — JSON:API pagination link 표준 (D7 근거, size cap 에 agnostic)
- raw/official-docs/rfc9110-http-semantics — HTTP semantics 기반 (pagination 자체보다 HTTP status 관련)
- raw/official-docs/google-aip-185-resource-versioning — 동일 AIP 계열, D2 근거
- raw/official-docs/api-versioning-google-aip-180 — 동일 AIP 계열, D6 근거
- 이 자료를 인용한 branch-note: raw/branch-notes/feature-api-contract-baseline (D18 Supporting Claim 보강)
- 이 자료를 인용한 wiki 요약: (생성 시 링크 추가)