refactor: unify pagination onto a single Page-based surface#145
Open
OmarAlJarrah wants to merge 1 commit into
Open
refactor: unify pagination onto a single Page-based surface#145OmarAlJarrah wants to merge 1 commit into
OmarAlJarrah wants to merge 1 commit into
Conversation
The SDK carried two parallel pagination implementations:
- pagination/* — Paginator + PaginationStrategy + Page, which drives
HTTP requests through an HttpClient, closes each response after the
strategy parses it, applies a maxPages safety cap, and ships cursor,
page-number, and link-header strategies.
- http/paging/* — PagedIterable + PagedResponse + PagingOptions, a
thinner first-/next-page fetcher abstraction whose byPage() sequence
leaked the underlying response (and pooled connection) on partial
consumption unless the caller closed every page by hand.
Two surfaces for the same job means duplicated concepts, divergent
close semantics, and a real connection leak in the second one. This
collapses everything onto the Paginator/Page stack — the more complete
one, with correct per-page response lifecycle — and removes the
PagedIterable stack entirely.
To preserve the page-level signals PagedResponse exposed, the Page
interface now carries optional response metadata (statusCode, headers)
and the HATEOAS links / continuation token (nextLink, previousLink,
firstLink, lastLink, continuationToken). The accessors default to null,
so existing third-party Page implementations keep compiling unchanged;
the bundled strategies populate the envelope and links they already
parse. LinkHeaderPaginationStrategy now extracts all four navigation
relations instead of only rel="next".
Public API: removes org.dexpace.sdk.core.http.paging.*; adds the default
metadata accessors to Page. api/sdk-core.api regenerated accordingly.
Closes #30
This was referenced Jun 17, 2026
Member
Author
|
Nice consolidation — folding the Issues
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
sdk-coreshipped two parallel pagination implementations:pagination/*—Paginator+PaginationStrategy+Page, which drives requests through anHttpClient, closes each response right after the strategy parses it, applies amaxPagessafety cap, and ships cursor, page-number, and link-header strategies.http/paging/*—PagedIterable+PagedResponse+PagingOptions, a thinner first-/next-page fetcher abstraction. ItsbyPage()sequence leaked the underlying response — and the pooled connection behind it — on partial consumption unless the caller manually closed every yielded page.Two surfaces for the same job meant duplicated concepts, divergent close semantics, and a genuine connection leak in the second one.
Change
Paginator/Pagestack — the more complete one, with correct per-page response lifecycle — and delete thePagedIterablestack (PagedIterable,PagedResponse,PagingOptions,FirstPageFetcher,NextPageFetcher) along with its test.PagedResponseexposed into the unifiedPage<T>contract: optionalstatusCodeandheaders, plus the HATEOAS links / continuation token (nextLink,previousLink,firstLink,lastLink,continuationToken). The accessors are interface defaults returningnull, so existing third-partyPageimplementations keep compiling unchanged.LinkHeaderPaginationStrategynow parses all four navigation relations (next/prev/first/last) instead of onlyrel="next";CursorPaginationStrategysurfaces the next cursor ascontinuationToken; all three recordstatusCodeandheaders.PageMetadataTestcovering the new accessors (defaults, link extraction across all relations, cursor token, status/headers on populated and empty pages).README.md,docs/architecture.md, anddocs/refs-comparison.mdto describe the single surface.The max-pages cap, per-page response close, and interrupt-aware blocking already lived in
Paginator; the byPage leak is gone because that path no longer exists. Item-level iteration (iterateAll()/streamAll()) was already leak-free — the paginator closes each response after parsing.Rationale
One pagination surface removes a maintenance hazard and a real resource leak, and it settles the page model before the first code-generator run (typed page classes and async pagination build on this).
Public API
Removes
org.dexpace.sdk.core.http.paging.*. Adds the default metadata accessors toPage.api/sdk-core.apiregenerated and committed.Coordination
This overlaps the QueryParams work in #28 — both touch
RequestRebuilder. Please sequence the merges so theRequestRebuilderchanges land cleanly.Gated build (scoped to
sdk-core)All four gates pass. One unrelated, pre-existing flaky concurrency test (
ContextStoreTest.concurrent untraced calls keep independent entries) intermittently NPEs; it passes in isolation and on re-run, and is untouched by this change.Closes #30