Files
llm-wiki/vault/20-evidence/official-docs/spring-data-pageable-defaults.md
T

13 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 / Spring Data — Pageable / Page Defaults official-doc https://docs.spring.io/spring-data/commons/reference/repositories/core-concepts.html Spring (VMware/Broadcom)
feature-api-contract-baseline
ca-skeleton
official-doc
ca-skeleton
api-design
spring-data
spring-mvc
offset-pagination
raw high 2026-05-31 2026-05-31

official-doc / Spring Data — Pageable / Page Defaults

Layer: raw/ — 외부 자료(공식 문서 / 대기업 기술 블로그)의 원문 발췌·출처 기록. 본 파일은 raw/official-docs/ 에 보관. 검증된 요약은 /ingestwiki/concepts/ 에 별도 작성. 원본은 raw 에 영구 보관.

Parent / 활용 branch (필수)

이 자료는 혼자 존재하지 않는다. 어느 branch 의 구현 결정의 근거로서 보관됨.

Branch 이 자료가 정당화하는 결정
raw/branch-notes/feature-api-contract-baseline D18: page 0-indexed (Spring Pageable default 와 정합), size default 20, maxPageSize default 2000 (unbounded ≠ project-internal cap 100) — DoS footgun 근거

출처 / Source

왜 저장했는지 / Why archived

D18 결정 (page 0-indexed, size default 20, max cap) 이 UNSUPPORTED_DECISION 으로 남아 있었기 때문이다. Spring 공식 문서가 Pageable 의 0-indexed default 와 size default 20 을 normative 하게 진술하므로, 본 raw 가 그 근거를 vendor-doc 강도로 직접 정당화한다. 추가로 PageableHandlerMethodArgumentResolverSupportDEFAULT_MAX_PAGE_SIZE = 2000spring 기본 unbounded 가 아님을 명시해, project 의 100 cap 이 별도 opt-in override 임을 구별하게 한다.

핵심 인용 / Key quotes (verbatim, self-grep 통과)

[§core-extensions — Request Parameters for Pageable table] "| page | Page you want to retrieve. 0-indexed | 0 |" (source: https://docs.spring.io/spring-data/commons/reference/repositories/core-extensions.html — request parameter table row, line 12 of fetched text)

[§core-extensions — Request Parameters for Pageable table] "| size | Size of the page you want to retrieve | 20 |" (source: https://docs.spring.io/spring-data/commons/reference/repositories/core-extensions.html — request parameter table row, line 13 of fetched text)

[§query-methods-details — Paging, Sorting & Limiting] "Pageable is zero-indexed (starts at 0). The infrastructure recognizes special types like Pageable, Sort, and Limit to apply dynamic pagination, sorting, and limiting." (source: https://docs.spring.io/spring-data/commons/reference/repositories/query-methods-details.html — Important note, line 15 of fetched text)

[§core-extensions — Default Pageable Value] "The default Pageable passed into the method is equivalent to: PageRequest.of(0, 20) // page=0, size=20" (source: https://docs.spring.io/spring-data/commons/reference/repositories/core-extensions.html — Default Pageable Value section, line 64 of fetched text)

[§PageableHandlerMethodArgumentResolverSupport Javadoc — setMaxPageSize] "Configures the maximum page size to be accepted. This prevents potential attacks trying to issue an OutOfMemoryError. Defaults to DEFAULT_MAX_PAGE_SIZE." (source: https://docs.spring.io/spring-data/commons/docs/current/api/org/springframework/data/web/PageableHandlerMethodArgumentResolverSupport.html — setMaxPageSize method, line 7 of fetched text)

[§PageableHandlerMethodArgumentResolverSupport source — constant] "DEFAULT_MAX_PAGE_SIZE = 2000" (source: https://github.com/spring-projects/spring-data-commons/blob/main/src/main/java/org/springframework/data/web/PageableHandlerMethodArgumentResolverSupport.java — line 24 of fetched text)

[§PageableHandlerMethodArgumentResolverSupport Javadoc — setOneIndexedParameters] "Default: false (page 0 = first page)" (source: https://docs.spring.io/spring-data/commons/docs/current/api/org/springframework/data/web/PageableHandlerMethodArgumentResolverSupport.html — setOneIndexedParameters, line 12 of fetched text)

Claims Extracted / 추출된 주장

이 자료가 직접 말하는 것만 claim 으로 분리한다. 내 프로젝트에 적용한 결론은 여기 쓰지 않는다.

Claim ID Claim (이 자료가 직접 말하는 것) Evidence quote Strength Applies to Does not prove
SPRING-PAGE-C1 Spring MVC 에서 Pageable 을 controller method argument 로 사용할 때 page request parameter 는 0-indexed 이며 default 값은 0 이다 [§core-extensions table] "Page you want to retrieve. 0-indexed | 0" official-vendor-doc Spring Data Web Support (@EnableSpringDataWebSupport) 활성화 시, PageableHandlerMethodArgumentResolver 등록 환경 1-indexed 방식이 Spring 에서 불가능하다는 뜻이 아님 (setOneIndexedParameters(true) opt-in 가능). 다른 프레임워크(JAX-RS 등)의 default 에는 적용 불가
SPRING-PAGE-C2 size request parameter 의 default 값은 20 이다 [§core-extensions table] "Size of the page you want to retrieve | 20" official-vendor-doc 동일 환경 (PageableHandlerMethodArgumentResolver 등록) size=0 또는 size=-1 의 처리 방식(reject/accept)은 본 인용에 명시되지 않음. default 만 정의, maximum 은 C4 참조
SPRING-PAGE-C3 Pageablezero-indexed (starts at 0) 이다 — query method layer 에서 normative 진술 [§query-methods-details] "Pageable is zero-indexed (starts at 0)." official-vendor-doc Spring Data repository query method 에 Pageable parameter 를 전달하는 모든 경우 request parameter 파싱 단계(MVC layer)의 behavior 를 직접 진술하는 것이 아닌, Spring Data 레포지토리 infrastructure 레벨의 Pageable 의미론. 두 레이어가 일관됨은 C1 이 보완
SPRING-PAGE-C4 PageableHandlerMethodArgumentResolverSupportsetMaxPageSizeDEFAULT_MAX_PAGE_SIZE 를 기본값으로 사용하며, 소스 코드에서 해당 상수는 2000 이다 [§Javadoc] "Configures the maximum page size to be accepted. This prevents potential attacks trying to issue an OutOfMemoryError. Defaults to DEFAULT_MAX_PAGE_SIZE." / [§source] "DEFAULT_MAX_PAGE_SIZE = 2000" official-vendor-doc PageableHandlerMethodArgumentResolverSupport 를 기반으로 하는 PageableHandlerMethodArgumentResolverReactivePageableHandlerMethodArgumentResolver DEFAULT_MAX_PAGE_SIZE = 2000 이 github source fetch 기준 값이며 버전별로 다를 수 있음. 본 raw 의 fetch 는 main branch 기준 — Spring Data Commons 4.0.x release 에서 상이할 가능성 요확인. "Integer.MAX_VALUE" 가 아닌 2000 이 default 라는 것이 핵심
SPRING-PAGE-C5 method 의 fallback Pageable (annotation 없을 때) 은 PageRequest.of(0, 20) 과 동등하다 [§core-extensions] "The default Pageable passed into the method is equivalent to: PageRequest.of(0, 20) // page=0, size=20" official-vendor-doc @PageableDefault annotation 이 없는 controller method parameter 에 Pageable 주입 시 @PageableDefault(size = N) 로 override 하면 달라짐. fallback 이 적용되는 것은 request parameter 가 아예 없을 때뿐 — ?page=0 이 명시되면 이 fallback 이 아닌 request 값 우선
SPRING-PAGE-C6 setOneIndexedParameters(boolean) 의 default 는 false 이므로 page 0 = first page 가 기본 동작이다 [§Javadoc] "Default: false (page 0 = first page)" official-vendor-doc PageableHandlerMethodArgumentResolver 기본 구성 (커스터마이징 없는 상태) setOneIndexedParameters(true) 로 바꾸면 page 1 = first page 로 전환 — 이 경우 클라이언트/서버 계약이 모두 1-indexed 로 변경됨. Spring Security 또는 별도 필터가 parameter 를 조작하는 경우 별도 검증 필요

Strength 허용값 사용 근거

모든 Claim 은 official-vendor-doc 이다 — Spring Data Commons 는 VMware/Broadcom 이 유지하는 공식 벤더 문서이며 IETF/W3C 표준이 아님.

Usage Boundaries / 적용 경계

  • 이 자료가 직접 증명하는 것:

    • SPRING-PAGE-C1: Spring Data Web Support 환경에서 page request parameter 가 0-indexed 이고 default = 0
    • SPRING-PAGE-C2: 동일 환경에서 size default = 20
    • SPRING-PAGE-C3: Spring Data 레포지토리 infrastructure 에서 Pageable 자체가 zero-indexed
    • SPRING-PAGE-C4: PageableHandlerMethodArgumentResolverSupport.DEFAULT_MAX_PAGE_SIZE = 2000 (source fetch 기준) — Spring 기본 max 가 별도 설정 없으면 2000 임을 의미하며, Integer.MAX_VALUE 처럼 완전히 unbounded 는 아님
    • SPRING-PAGE-C5: annotation 없는 경우 fallback = PageRequest.of(0, 20)
    • SPRING-PAGE-C6: setOneIndexedParameters default = false → page 0 = first page 가 기본
  • 이 자료가 증명하지 않는 것:

    • Spring docs 가 vendor-doc 이며 IETF/W3C 표준이 아님 — official-vendor-doc strength 이므로 표준 lock-in 근거가 될 수 없음
    • size 의 상한이 "없다" (unbounded) 는 주장 — Spring 은 DEFAULT_MAX_PAGE_SIZE = 2000 을 기본 상한으로 가짐. 단 2000 은 project 의 100 cap 보다 훨씬 크므로 DoS footgun 은 여전히 유효
    • project 의 size max 100 cap 결정은 Spring docs 의 기본 동작 이 아니라 project-internal opt-in override — 본 raw 는 Spring default behavior 만 정당화하며, 100 cap 선택은 D18 의 project-internal trade-off
    • Pageable 의 동작이 Spring Data Commons 버전별로 동일함 — 본 raw 는 fetch 시점 (2026-05-31) 의 latest stable 문서 기준. DEFAULT_MAX_PAGE_SIZE 등의 상수는 버전업 시 변경될 수 있음
    • 다른 WAS(Undertow, Netty) 또는 다른 Spring 구성(reactive)에서의 동작 — 본 인용은 Servlet stack + PageableHandlerMethodArgumentResolver 기준
  • 내 프로젝트에 적용하려면 추가 확인이 필요한 것:

    • @EnableSpringDataWebSupport 가 ca-skeleton 의 WebMvcConfigurer 에 적용되어 있는지 확인 (없으면 Pageable 자동 binding 미동작)
    • maxPageSize 가 기본 2000 이라면 project 의 100 cap 은 PageableHandlerMethodArgumentResolversetMaxPageSize(100) 또는 별도 @PageableDefault + validator 를 통해 강제해야 함 — Spring 기본값에 의존하면 2000 까지 허용됨
    • setOneIndexedParameters 가 false (default) 로 유지되는지 — ca-skeleton 설정에서 이를 true 로 변경하면 0-indexed 정합이 깨짐

메모 / Notes

  • DEFAULT_MAX_PAGE_SIZE = 2000 값은 github main branch source 에서 확인했으며, Spring Data Commons 공식 released Javadoc 에는 상수의 실제 값이 직접 노출되지 않음. release 버전 확인 시 spring-data-commons-x.y.z.jarPageableHandlerMethodArgumentResolverSupport.class 를 디컴파일하거나 release notes 에서 확인 권장.
  • D18 의 "Spring 기본 max = Integer.MAX_VALUE 라서 DoS footgun" 이라는 기존 설명은 부정확했음. 실제 default max 는 2000 이지만, project 의 비즈니스 요구 상 100 으로 cap 하는 것은 여전히 합리적인 trade-off.
  • Spring MVC 에서 Pageable 바인딩이 동작하려면 spring-data-commons + spring-data-web 의존성이 classpath 에 있어야 하고 @EnableSpringDataWebSupport 가 활성화되어 있어야 함.
  • 추가로 봐야 할 동일 출처 페이지: Google AIP-158 (cursor pagination shape), JSON:API pagination format (D7 근거).