File tree Expand file tree Collapse file tree 5 files changed +45
-1
lines changed
Expand file tree Collapse file tree 5 files changed +45
-1
lines changed Original file line number Diff line number Diff line change @@ -38,6 +38,8 @@ and this project adheres to
3838 (including ` describedby ` )
3939- Add ` Schema\Link ` class for defining rich link objects with metadata
4040- Add ` JsonApiError::id(string $id) ` method for setting error IDs
41+ - Add ` Page::$rangeTruncated ` parameter for cursor pagination range truncation
42+ support
4143- Add full support for JSON: API profiles:
4244 - Parse profile URIs from ` Accept ` header
4345 - ` Context::profileRequested(string $uri): bool ` - check if a profile was
Original file line number Diff line number Diff line change @@ -118,7 +118,11 @@ class PostsResource extends AbstractResource implements
118118 ): Page {
119119 // ...
120120
121- return new Page($results, $isFirstPage, $isLastPage);
121+ return new Page(
122+ results: $results,
123+ isFirstPage: $isFirstPage,
124+ isLastPage: $isLastPage,
125+ );
122126 }
123127
124128 public function itemCursor($model, object $query, Context $context): string
@@ -128,6 +132,24 @@ class PostsResource extends AbstractResource implements
128132}
129133```
130134
135+ ### Range Pagination
136+
137+ When both ` after ` and ` before ` cursors are provided, implementations can support
138+ range-based pagination. If the results were truncated to fit within the
139+ specified range, set the ` rangeTruncated ` parameter:
140+
141+ ``` php
142+ return new Page(
143+ results: $results,
144+ isFirstPage: false,
145+ isLastPage: false,
146+ rangeTruncated: true,
147+ );
148+ ```
149+
150+ This will add ` {"page": {"rangeTruncated": true}} ` to the document's ` meta `
151+ object to inform clients that not all items in the range were returned.
152+
131153## Countability
132154
133155By default, offset pagination won't include a ` last ` link because there is no
Original file line number Diff line number Diff line change @@ -70,6 +70,10 @@ public function paginate(object $query, Context $context): array
7070 ]);
7171 }
7272
73+ if ($ page ->rangeTruncated !== null ) {
74+ $ context ->documentMeta ['page ' ]['rangeTruncated ' ] = $ page ->rangeTruncated ;
75+ }
76+
7377 return $ page ->results ;
7478 }
7579
Original file line number Diff line number Diff line change @@ -8,6 +8,7 @@ public function __construct(
88 public array $ results ,
99 public ?bool $ isFirstPage = null ,
1010 public ?bool $ isLastPage = null ,
11+ public ?bool $ rangeTruncated = null ,
1112 ) {
1213 }
1314}
Original file line number Diff line number Diff line change @@ -163,4 +163,19 @@ public function test_unknown_cursor_returns_invalid_parameter_error(): void
163163 $ this ->assertStringContainsString ('after ' , $ error ['source ' ]['parameter ' ] ?? '' );
164164 }
165165 }
166+
167+ public function test_range_truncation_meta_is_included_when_results_truncated (): void
168+ {
169+ $ response = $ this ->api ->handle (
170+ $ this ->buildRequest ('GET ' , '/articles ' )->withQueryParams ([
171+ 'page ' => ['before ' => '5 ' , 'size ' => '2 ' ],
172+ ]),
173+ );
174+
175+ $ data = json_decode ($ response ->getBody (), true );
176+
177+ $ this ->assertArrayHasKey ('meta ' , $ data );
178+ $ this ->assertArrayHasKey ('page ' , $ data ['meta ' ]);
179+ $ this ->assertTrue ($ data ['meta ' ]['page ' ]['rangeTruncated ' ]);
180+ }
166181}
You can’t perform that action at this time.
0 commit comments