Skip to content

Commit 158c0cf

Browse files
authored
Rename cursorPaginate() to cursor() and add comparison docs (#24)
Shorter, cleaner API for cursor-based pagination. Also replaces the comparison table with a more readable list format and updates all docs to reference cursor() instead of cursorPaginate().
1 parent 8a763ea commit 158c0cf

8 files changed

Lines changed: 26 additions & 10 deletions

File tree

docs/1.basics/3.query-builder.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ class ProductController
127127
->paginate()
128128

129129
// Cursor pagination: ?page[cursor]=eyJpZCI6MTB9&page[size]=20
130-
->cursorPaginate()
130+
->cursor()
131131

132132
// No pagination, returns all results
133133
->get()

docs/1.index.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,22 @@ API Toolkit is a Laravel package that gives you everything you need to build [JS
1919
- **Testing Utilities** - Chainable assertions purpose-built for JSON:API responses
2020
- **Middleware** - Force JSON:API content type on all responses
2121

22+
## Why API Toolkit?
23+
24+
Laravel 12.45 introduced `JsonApiResource` for basic JSON:API serialization, covering type/id/attributes structure, relationships, included resources, and sparse fieldsets.
25+
26+
API Toolkit builds on top of that with:
27+
28+
- **Type-safe resources** - Typed model parameters instead of magic `$this->name` via `__get`
29+
- **Non-Eloquent support** - Works with any object: DTOs, Carbon, stdClass, and more
30+
- **Filtering** - Exact, partial, date, and scope-based filters via `?filter[status]=active`
31+
- **Sorting** - `?sort=-created_at` parsed and applied automatically
32+
- **Pagination** - Offset and cursor-based with meta and links
33+
- **Query validation** - Strict rejection of unknown parameters
34+
- **Error responses** - JSON:API errors with source pointers for validation failures
35+
- **OpenAPI 3.1** - Auto-generated from your routes and resources
36+
- **Testing** - Chainable assertions for Pest and PHPUnit
37+
2238
## Requirements
2339

2440
- PHP 8.4+

docs/2.filtering-and-sorting/3.pagination.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,12 +47,12 @@ GET /api/products?page[number]=2&page[size]=20
4747

4848
## Cursor Pagination
4949

50-
More efficient for large datasets. Use `->cursorPaginate()`.
50+
More efficient for large datasets. Use `->cursor()`.
5151

5252
```php
5353
return QueryBuilder::for(Product::class, $request)
5454
->fromResource(ProductResource::class)
55-
->cursorPaginate();
55+
->cursor();
5656
```
5757

5858
### Query Parameters

src/OpenApi/RouteScanner.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -169,12 +169,12 @@ private function resolveClassName(string $shortName, string $controllerClass): s
169169
}
170170

171171
/**
172-
* Determine if this endpoint returns a collection (uses paginate/cursorPaginate/get on QueryBuilder).
172+
* Determine if this endpoint returns a collection (uses paginate/cursor/get on QueryBuilder).
173173
*/
174174
private function isListEndpoint(string $source): bool
175175
{
176176
return str_contains($source, '->paginate(')
177-
|| str_contains($source, '->cursorPaginate(')
177+
|| str_contains($source, '->cursor(')
178178
|| str_contains($source, 'QueryBuilder::for(');
179179
}
180180

src/QueryBuilder.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ public function paginate(): SuccessResponse
117117
return $this->toSuccessResponse($data);
118118
}
119119

120-
public function cursorPaginate(): SuccessResponse
120+
public function cursor(): SuccessResponse
121121
{
122122
$this->applyAll();
123123

tests/Feature/OpenApi/RouteScannerTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@
101101
expect($endpoints)->toBe([]);
102102
});
103103

104-
it('detects cursorPaginate as list endpoint', function () {
104+
it('detects cursor as list endpoint', function () {
105105
Route::get('/api/v1/products', [ScannerStubCursorController::class, '__invoke']);
106106

107107
$scanner = app(RouteScanner::class);

tests/Feature/QueryBuilderTest.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,7 @@
169169
expect($array)->toHaveKey('links');
170170
});
171171

172-
it('returns a SuccessResponse from cursorPaginate', function () {
172+
it('returns a SuccessResponse from cursor', function () {
173173
Product::create([
174174
'public_id' => 'prod-1',
175175
'name' => 'Widget',
@@ -182,7 +182,7 @@
182182

183183
$result = QueryBuilder::for(Product::class, $request)
184184
->fromResource(ProductResource::class)
185-
->cursorPaginate()
185+
->cursor()
186186
;
187187

188188
expect($result)->toBeInstanceOf(SuccessResponse::class);

tests/Fixtures/Controllers/ScannerStubCursorController.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ public function __invoke(Request $request, Response $response): JsonResponse
1717
{
1818
return QueryBuilder::for(Product::class, $request)
1919
->fromResource(ProductResource::class)
20-
->cursorPaginate()
20+
->cursor()
2121
->respond()
2222
;
2323
}

0 commit comments

Comments
 (0)