Repository: Lomkit/laravel-rest-api (php)

Issue:
Add the ability to change the default limit on a resource
### Description

Currently the default limit of the response is 50 items. I thought it would be useful to give the user the ability to add an attribute $defaultLimit on the resources so that it can be tailored to the app's need.

Pull request:
Define default limit
closes #157 

This PR adds the possibility of defining a default pagnination limit for a specific model.

If not defined, the value remains 50.

I took the opportunity to update the `Resource` models with this new feature.

It will be necessary to update the doc according to.

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit

- **New Features**
  - Enhanced pagination to use a configurable default limit for displayed items.
  - Introduced a new API endpoint that demonstrates customizable pagination behavior.

- **Tests**
  - Added test cases verifying that resources return the correct default number of items per page in various scenarios.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

Patch:
diff --git a/README.md b/README.md
index a8d96d2..2e0c37e 100644
--- a/README.md
+++ b/README.md
@@ -90,4 +90,4 @@ Here is a quick look at what you can do using API search method:
 
 - Metrics support
 - Refactor the response class
-- Alias for includes / aggregates
+- Alias for includes
diff --git a/src/Concerns/Resource/ConfiguresRestParameters.php b/src/Concerns/Resource/ConfiguresRestParameters.php
index 3564b0d..681d34f 100644
--- a/src/Concerns/Resource/ConfiguresRestParameters.php
+++ b/src/Concerns/Resource/ConfiguresRestParameters.php
@@ -47,7 +47,7 @@ trait ConfiguresRestParameters
      *
      * @return bool
      */
-    public function isNestedField(string $field, Relation $relation = null)
+    public function isNestedField(string $field, ?Relation $relation = null)
     {
         if (Str::contains($field, '.')) {
             // In case we are on a pivot we look for the relation pivot fields
diff --git a/src/Concerns/Resource/Paginable.php b/src/Concerns/Resource/Paginable.php
index a96becb..80ec607 100644
--- a/src/Concerns/Resource/Paginable.php
+++ b/src/Concerns/Resource/Paginable.php
@@ -17,11 +17,13 @@ trait Paginable
      */
     public function paginate($query, RestRequest $request)
     {
+        $defaultLimit = $this->defaultLimit ?? 50;
+
         // In case we have a scout builder
         if ($query instanceof Builder) {
-            return $query->paginate($request->input('search.limit', 50), 'page', $request->input('search.page', 1));
+            return $query->paginate($request->input('search.limit', $defaultLimit), 'page', $request->input('search.page', 1));
         }
 
-        return $query->paginate($request->input('search.limit', 50), ['*'], 'page', $request->input('search.page', 1));
+        return $query->paginate($request->input('search.limit', $defaultLimit), ['*'], 'page', $request->input('search.page', 1));
     }
 }
diff --git a/src/Console/stubs/resource.stub b/src/Console/stubs/resource.stub
index 2fa9d70..bf60b3c 100644
--- a/src/Console/stubs/resource.stub
+++ b/src/Console/stubs/resource.stub
@@ -13,6 +13,13 @@ class {{ class }} extends RestResource
      */
     public static $model = \{{ namespacedModel }}::class;
 
+    /**
+     * The default value for the pagination limit.
+     *
+     * @var int
+     */
+    public int $defaultLimit = 50;
+
     /**
      * The exposed fields that could be provided
      * @param RestRequest $request
diff --git a/src/Console/stubs/user-resource.stub b/src/Console/stubs/user-resource.stub
index a058a17..aa1a43b 100644
--- a/src/Console/stubs/user-resource.stub
+++ b/src/Console/stubs/user-resource.stub
@@ -13,6 +13,13 @@ class UserResource extends RestResource
      */
     public static $model = \App\User::class;
 
+    /**
+     * The default value for the pagination limit.
+     *
+     * @var int
+     */
+    public int $defaultLimit = 50;
+
     /**
      * The exposed fields that could be provided
      * @param RestRequest $request
diff --git a/src/Contracts/RelationResource.php b/src/Contracts/RelationResource.php
index 6b74570..678e695 100644
--- a/src/Contracts/RelationResource.php
+++ b/src/Contracts/RelationResource.php
@@ -7,5 +7,5 @@ use Illuminate\Database\Eloquent\Builder;
 
 interface RelationResource
 {
-    public function filter(Builder $query, $relation, $operator, $value, $boolean = 'and', Closure $callback = null);
+    public function filter(Builder $query, $relation, $operator, $value, $boolean = 'and', ?Closure $callback = null);
 }
diff --git a/src/Documentation/Schemas/Info.php b/src/Documentation/Schemas/Info.php
index 8309029..fe7a0ac 100644
--- a/src/Documentation/Schemas/Info.php
+++ b/src/Documentation/Schemas/Info.php
@@ -30,7 +30,7 @@ class Info extends Schema
      *
      * @var string|null
      */
-    protected string|null $termsOfService;
+    protected ?string $termsOfService;
 
     /**
      * The contact information for the exposed API.
@@ -132,7 +132,7 @@ class Info extends Schema
      *
      * @return Info
      */
-    public function withTermsOfService(string|null $termsOfService): Info
+    public function withTermsOfService(?string $termsOfService): Info
     {
         $this->termsOfService = $termsOfService;
 
@@ -144,7 +144,7 @@ class Info extends Schema
      *
      * @return string|null
      */
-    public function termsOfService(): string|null
+    public function termsOfService(): ?string
     {
         return $this->termsOfService;
     }
diff --git a/src/Documentation/Schemas/License.php b/src/Documentation/Schemas/License.php
index 190dd65..d676fc3 100644
--- a/src/Documentation/Schemas/License.php
+++ b/src/Documentation/Schemas/License.php
@@ -23,7 +23,7 @@ class License extends Schema
      *
      * @var string
      */
-    protected string|null $url;
+    protected ?string $url;
 
     /**
      * Set the name of the license used for the API.
@@ -80,7 +80,7 @@ class License extends Schema
      *
      * @return License
      */
-    public function withUrl(string|null $url): License
+    public function withUrl(?string $url): License
     {
         $this->url = $url;
 
@@ -92,7 +92,7 @@ class License extends Schema
      *
      * @return string|null
      */
-    public function url(): string|null
+    public function url(): ?string
     {
         return $this->url;
     }
diff --git a/src/Http/Resource.php b/src/Http/Resource.php
index 9541529..b4fa922 100644
--- a/src/Http/Resource.php
+++ b/src/Http/Resource.php
@@ -46,6 +46,13 @@ class Resource implements \JsonSerializable
      */
     public static $response = Response::class;
 
+    /**
+     * The default value for the pagination limit.
+     *
+     * @var int
+     */
+    public int $defaultLimit = 50;
+
     /**
      * Get a fresh instance of the model represented by the resource.
      *
diff --git a/src/Http/Response.php b/src/Http/Response.php
index cef1aea..83428fd 100644
--- a/src/Http/Response.php
+++ b/src/Http/Response.php
@@ -53,7 +53,7 @@ class Response implements Responsable
      *
      * @return array The structured array representation of the model, including attributes and recursively processed relations.
      */
-    public function modelToResponse(Model $model, Resource $resource, array $requestArray, Relation $relation = null)
+    public function modelToResponse(Model $model, Resource $resource, array $requestArray, ?Relation $relation = null)
     {
         $currentRequestArray = $relation === null ? $requestArray : collect($requestArray['includes'] ?? [])
             ->first(function ($include) use ($relation) {
@@ -71,7 +71,7 @@ class Response implements Responsable
                         // Here we add the aggregates
                         collect($currentRequestArray['aggregates'] ?? [])
                             ->map(function ($aggregate) {
-                                return Str::snake($aggregate['relation']).'_'.$aggregate['type'].(isset($aggregate['field']) ? '_'.$aggregate['field'] : '');
+                                return $aggregate['alias'] ?? Str::snake($aggregate['relation']).'_'.$aggregate['type'].(isset($aggregate['field']) ? '_'.$aggregate['field'] : '');
                             })
                             ->toArray()
                     )
diff --git a/src/Query/Builder.php b/src/Query/Builder.php
index b494adc..4c7f72a 100644
--- a/src/Query/Builder.php
+++ b/src/Query/Builder.php
@@ -24,7 +24,7 @@ class Builder implements QueryBuilder
      *
      * @return void
      */
-    public function __construct(Resource $resource, \Illuminate\Database\Eloquent\Builder|Relation $query = null)
+    public function __construct(Resource $resource, \Illuminate\Database\Eloquent\Builder|Relation|null $query = null)
     {
         $this->resource = $resource;
         $this->queryBuilder = $query ?? $resource::newModel()->query();
diff --git a/src/Query/ScoutBuilder.php b/src/Query/ScoutBuilder.php
index 53f7f13..5d375dc 100644
--- a/src/Query/ScoutBuilder.php
+++ b/src/Query/ScoutBuilder.php
@@ -49,7 +49,8 @@ class ScoutBuilder implements QueryBuilder
             $this->applyInstructions($parameters['instructions']);
         });
 
-        $this->queryBuilder->take($parameters['limit'] ?? 50);
+        $defaultLimit = $this->resource->defaultLimit ?? 50;
+        $this->queryBuilder->take($parameters['limit'] ?? $defaultLimit);
 
         $this->queryBuilder
             ->query(function (Builder $query) use ($parameters) {
diff --git a/src/Query/Traits/PerformSearch.php b/src/Query/Traits/PerformSearch.php
index 6d156f1..a2b468f 100644
--- a/src/Query/Traits/PerformSearch.php
+++ b/src/Query/Traits/PerformSearch.php
@@ -237,7 +237,13 @@ trait PerformSearch
      */
     public function aggregate($aggregate)
     {
-        return $this->queryBuilder->withAggregate([$aggregate['relation'] => function (Builder $query) use ($aggregate) {
+        $relation = $aggregate['relation'];
+
+        if (isset($aggregate['alias'])) {
+            $relation .= ' as '.$aggregate['alias'];
+        }
+
+        return $this->queryBuilder->withAggregate([$relation => function (Builder $query) use ($aggregate) {
             $resource = $this->resource->relation($aggregate['relation'])?->resource();
 
             $queryBuilder = $this->newQueryBuilder(['resource' => $resource, 'query' => $query]);
diff --git a/src/Relations/Relation.php b/src/Relations/Relation.php
index 3f8aa32..c819684 100644
--- a/src/Relations/Relation.php
+++ b/src/Relations/Relation.php
@@ -57,7 +57,7 @@ class Relation implements \JsonSerializable
      *
      * @return Builder
      */
-    public function filter(Builder $query, $relation, $operator, $value, $boolean = 'and', Closure $callback = null)
+    public function filter(Builder $query, $relation, $operator, $value, $boolean = 'and', ?Closure $callback = null)
     {
         return $query->has(Str::beforeLast(relation_without_pivot($relation), '.'), '>=', 1, $boolean, function (Builder $query) use ($value, $operator, $relation, $callback) {
             $field = (Str::contains($relation, '.pivot.') ?
diff --git a/src/Rules/MutateRules.php b/src/Rules/MutateRules.php
index 0e77ef4..7c5682b 100644
--- a/src/Rules/MutateRules.php
+++ b/src/Rules/MutateRules.php
@@ -40,7 +40,7 @@ class MutateRules implements ValidationRule, ValidatorAwareRule
      *
      * @var Relation|null
      */
-    protected Relation|null $relation;
+    protected ?Relation $relation;
 
     /**
      * Specify if the validation is at root level.
@@ -49,7 +49,7 @@ class MutateRules implements ValidationRule, ValidatorAwareRule
      */
     protected bool $isRootValidation;
 
-    public function __construct(\Lomkit\Rest\Http\Resource $resource, RestRequest $request, Relation $relation = null, bool $isRootValidation = false)
+    public function __construct(\Lomkit\Rest\Http\Resource $resource, RestRequest $request, ?Relation $relation = null, bool $isRootValidation = false)
     {
         $this->resource = $resource;
         $this->request = $request;
diff --git a/src/Rules/SearchRules.php b/src/Rules/SearchRules.php
index d1033af..e846b79 100644
--- a/src/Rules/SearchRules.php
+++ b/src/Rules/SearchRules.php
@@ -341,6 +341,10 @@ class SearchRules implements ValidationRule, ValidatorAwareRule
                 'required_if:'.$prefix.'.*.type,min,max,avg,sum',
                 'prohibited_if:'.$prefix.'.*.type,count,exists',
             ],
+            $prefix.'.*.alias' => [
+                'nullable',
+                'string',
+            ],
             $prefix.'.*' => [
                 AggregateField::make()
                     ->resource($resource),


Test patch:
diff --git a/tests/Feature/Controllers/SearchAggregatesOperationsTest.php b/tests/Feature/Controllers/SearchAggregatesOperationsTest.php
index 11fc72b..3380b1e 100644
--- a/tests/Feature/Controllers/SearchAggregatesOperationsTest.php
+++ b/tests/Feature/Controllers/SearchAggregatesOperationsTest.php
@@ -192,6 +192,52 @@ class SearchAggregatesOperationsTest extends TestCase
         );
     }
 
+    public function test_getting_a_list_of_resources_aggregating_by_min_number_with_alias(): void
+    {
+        $matchingModel = ModelFactory::new()
+            ->has(
+                BelongsToManyRelationFactory::new()
+                    ->count(20)
+            )
+            ->create()->fresh();
+        $matchingModel2 = ModelFactory::new()
+            ->has(
+                BelongsToManyRelationFactory::new()
+                    ->count(20)
+            )
+            ->create()->fresh();
+
+        Gate::policy(Model::class, GreenPolicy::class);
+        Gate::policy(BelongsToManyRelation::class, GreenPolicy::class);
+
+        $response = $this->post(
+            '/api/models/search',
+            [
+                'search' => [
+                    'aggregates' => [
+                        [
+                            'relation' => 'belongsToManyRelation',
+                            'type'     => 'min',
+                            'field'    => 'number',
+                            'alias'    => 'min_alias',
+                        ],
+                    ],
+                ],
+            ],
+            ['Accept' => 'application/json']
+        );
+
+        $this->assertResourcePaginated(
+            $response,
+            [$matchingModel, $matchingModel2],
+            new ModelResource(),
+            [
+                ['min_alias' => $matchingModel->belongsToManyRelation()->orderBy('number', 'asc')->first()->number],
+                ['min_alias' => $matchingModel2->belongsToManyRelation()->orderBy('number', 'asc')->first()->number],
+            ]
+        );
+    }
+
     public function test_getting_a_list_of_resources_aggregating_by_max_number(): void
     {
         $matchingModel = ModelFactory::new()
@@ -237,6 +283,52 @@ class SearchAggregatesOperationsTest extends TestCase
         );
     }
 
+    public function test_getting_a_list_of_resources_aggregating_by_max_number_with_alias(): void
+    {
+        $matchingModel = ModelFactory::new()
+            ->has(
+                BelongsToManyRelationFactory::new()
+                    ->count(20)
+            )
+            ->create()->fresh();
+        $matchingModel2 = ModelFactory::new()
+            ->has(
+                BelongsToManyRelationFactory::new()
+                    ->count(20)
+            )
+            ->create()->fresh();
+
+        Gate::policy(Model::class, GreenPolicy::class);
+        Gate::policy(BelongsToManyRelation::class, GreenPolicy::class);
+
+        $response = $this->post(
+            '/api/models/search',
+            [
+                'search' => [
+                    'aggregates' => [
+                        [
+                            'relation' => 'belongsToManyRelation',
+                            'type'     => 'max',
+                            'field'    => 'number',
+                            'alias'    => 'max_alias',
+                        ],
+                    ],
+                ],
+            ],
+            ['Accept' => 'application/json']
+        );
+
+        $this->assertResourcePaginated(
+            $response,
+            [$matchingModel, $matchingModel2],
+            new ModelResource(),
+            [
+                ['max_alias' => $matchingModel->belongsToManyRelation()->orderBy('number', 'desc')->first()->number],
+                ['max_alias' => $matchingModel2->belongsToManyRelation()->orderBy('number', 'desc')->first()->number],
+            ]
+        );
+    }
+
     public function test_getting_a_list_of_resources_aggregating_by_avg_number(): void
     {
         $matchingModel = ModelFactory::new()
@@ -282,6 +374,52 @@ class SearchAggregatesOperationsTest extends TestCase
         );
     }
 
+    public function test_getting_a_list_of_resources_aggregating_by_avg_number_with_alias(): void
+    {
+        $matchingModel = ModelFactory::new()
+            ->has(
+                BelongsToManyRelationFactory::new()
+                    ->count(20)
+            )
+            ->create()->fresh();
+        $matchingModel2 = ModelFactory::new()
+            ->has(
+                BelongsToManyRelationFactory::new()
+                    ->count(20)
+            )
+            ->create()->fresh();
+
+        Gate::policy(Model::class, GreenPolicy::class);
+        Gate::policy(BelongsToManyRelation::class, GreenPolicy::class);
+
+        $response = $this->post(
+            '/api/models/search',
+            [
+                'search' => [
+                    'aggregates' => [
+                        [
+                            'relation' => 'belongsToManyRelation',
+                            'type'     => 'avg',
+                            'field'    => 'number',
+                            'alias'    => 'avg_alias',
+                        ],
+                    ],
+                ],
+            ],
+            ['Accept' => 'application/json']
+        );
+
+        $this->assertResourcePaginated(
+            $response,
+            [$matchingModel, $matchingModel2],
+            new ModelResource(),
+            [
+                ['avg_alias' => $matchingModel->belongsToManyRelation()->avg('belongs_to_many_relations.number')],
+                ['avg_alias' => $matchingModel2->belongsToManyRelation()->avg('belongs_to_many_relations.number')],
+            ]
+        );
+    }
+
     public function test_getting_a_list_of_resources_aggregating_by_sum_number(): void
     {
         $matchingModel = ModelFactory::new()
@@ -327,6 +465,52 @@ class SearchAggregatesOperationsTest extends TestCase
         );
     }
 
+    public function test_getting_a_list_of_resources_aggregating_by_sum_number_with_alias(): void
+    {
+        $matchingModel = ModelFactory::new()
+            ->has(
+                BelongsToManyRelationFactory::new()
+                    ->count(20)
+            )
+            ->create()->fresh();
+        $matchingModel2 = ModelFactory::new()
+            ->has(
+                BelongsToManyRelationFactory::new()
+                    ->count(20)
+            )
+            ->create()->fresh();
+
+        Gate::policy(Model::class, GreenPolicy::class);
+        Gate::policy(BelongsToManyRelation::class, GreenPolicy::class);
+
+        $response = $this->post(
+            '/api/models/search',
+            [
+                'search' => [
+                    'aggregates' => [
+                        [
+                            'relation' => 'belongsToManyRelation',
+                            'type'     => 'sum',
+                            'field'    => 'number',
+                            'alias'    => 'sum_alias',
+                        ],
+                    ],
+                ],
+            ],
+            ['Accept' => 'application/json']
+        );
+
+        $this->assertResourcePaginated(
+            $response,
+            [$matchingModel, $matchingModel2],
+            new ModelResource(),
+            [
+                ['sum_alias' => $matchingModel->belongsToManyRelation()->sum('belongs_to_many_relations.number')],
+                ['sum_alias' => $matchingModel2->belongsToManyRelation()->sum('belongs_to_many_relations.number')],
+            ]
+        );
+    }
+
     public function test_getting_a_list_of_resources_aggregating_by_count_relation(): void
     {
         $matchingModel = ModelFactory::new()
@@ -371,6 +555,51 @@ class SearchAggregatesOperationsTest extends TestCase
         );
     }
 
+    public function test_getting_a_list_of_resources_aggregating_by_count_relation_with_alias(): void
+    {
+        $matchingModel = ModelFactory::new()
+            ->has(
+                BelongsToManyRelationFactory::new()
+                    ->count(20)
+            )
+            ->create()->fresh();
+        $matchingModel2 = ModelFactory::new()
+            ->has(
+                BelongsToManyRelationFactory::new()
+                    ->count(20)
+            )
+            ->create()->fresh();
+
+        Gate::policy(Model::class, GreenPolicy::class);
+        Gate::policy(BelongsToManyRelation::class, GreenPolicy::class);
+
+        $response = $this->post(
+            '/api/models/search',
+            [
+                'search' => [
+                    'aggregates' => [
+                        [
+                            'relation' => 'belongsToManyRelation',
+                            'type'     => 'count',
+                            'alias'    => 'count_alias',
+                        ],
+                    ],
+                ],
+            ],
+            ['Accept' => 'application/json']
+        );
+
+        $this->assertResourcePaginated(
+            $response,
+            [$matchingModel, $matchingModel2],
+            new ModelResource(),
+            [
+                ['count_alias' => $matchingModel->belongsToManyRelation()->count()],
+                ['count_alias' => $matchingModel2->belongsToManyRelation()->count()],
+            ]
+        );
+    }
+
     public function test_getting_a_list_of_resources_aggregating_by_exists_relation(): void
     {
         $matchingModel = ModelFactory::new()
@@ -411,6 +640,47 @@ class SearchAggregatesOperationsTest extends TestCase
         );
     }
 
+    public function test_getting_a_list_of_resources_aggregating_by_exists_relation_with_alias(): void
+    {
+        $matchingModel = ModelFactory::new()
+            ->create()->fresh();
+        $matchingModel2 = ModelFactory::new()
+            ->has(
+                BelongsToManyRelationFactory::new()
+                    ->count(20)
+            )
+            ->create()->fresh();
+
+        Gate::policy(Model::class, GreenPolicy::class);
+        Gate::policy(BelongsToManyRelation::class, GreenPolicy::class);
+
+        $response = $this->post(
+            '/api/models/search',
+            [
+                'search' => [
+                    'aggregates' => [
+                        [
+                            'relation' => 'belongsToManyRelation',
+                            'type'     => 'exists',
+                            'alias'    => 'exists_alias',
+                        ],
+                    ],
+                ],
+            ],
+            ['Accept' => 'application/json']
+        );
+
+        $this->assertResourcePaginated(
+            $response,
+            [$matchingModel, $matchingModel2],
+            new ModelResource(),
+            [
+                ['exists_alias' => false],
+                ['exists_alias' => true],
+            ]
+        );
+    }
+
     public function test_getting_a_list_of_resources_aggregating_by_min_number_with_filters(): void
     {
         $matchingModel = ModelFactory::new()
diff --git a/tests/Feature/Controllers/SearchPaginateOperationsTest.php b/tests/Feature/Controllers/SearchPaginateOperationsTest.php
index 3a7458b..e297f51 100644
--- a/tests/Feature/Controllers/SearchPaginateOperationsTest.php
+++ b/tests/Feature/Controllers/SearchPaginateOperationsTest.php
@@ -82,4 +82,22 @@ class SearchPaginateOperationsTest extends TestCase
             new ModelResource()
         );
     }
+
+    public function test_to_get_a_list_of_paginated_resources_from_the_default_limit(): void
+    {
+        ModelFactory::new()->count(100)->create()->fresh();
+
+        Gate::policy(Model::class, GreenPolicy::class);
+
+        $response = $this->post(
+            '/api/model-with-default-limit/search',
+            [],
+            ['Accept' => 'application/json']
+        );
+
+        $response->assertStatus(200);
+        $response->assertJsonPath('per_page', 32);
+        $response->assertJsonPath('last_page', 4);
+        $response->assertJsonCount(32, 'data');
+    }
 }
diff --git a/tests/Support/Http/Controllers/ModelWithDefaultLimitController.php b/tests/Support/Http/Controllers/ModelWithDefaultLimitController.php
new file mode 100644
index 0000000..832fe9c
--- /dev/null
+++ b/tests/Support/Http/Controllers/ModelWithDefaultLimitController.php
@@ -0,0 +1,11 @@
+<?php
+
+namespace Lomkit\Rest\Tests\Support\Http\Controllers;
+
+use Lomkit\Rest\Http\Controllers\Controller;
+use Lomkit\Rest\Tests\Support\Rest\Resources\ModelWithDefaultLimitResource;
+
+class ModelWithDefaultLimitController extends Controller
+{
+    public static $resource = ModelWithDefaultLimitResource::class;
+}
diff --git a/tests/Support/Rest/Resources/ModelWithDefaultLimitResource.php b/tests/Support/Rest/Resources/ModelWithDefaultLimitResource.php
new file mode 100644
index 0000000..ba7dde9
--- /dev/null
+++ b/tests/Support/Rest/Resources/ModelWithDefaultLimitResource.php
@@ -0,0 +1,8 @@
+<?php
+
+namespace Lomkit\Rest\Tests\Support\Rest\Resources;
+
+class ModelWithDefaultLimitResource extends ModelResource
+{
+    public int $defaultLimit = 32;
+}
diff --git a/tests/Support/Routes/api.php b/tests/Support/Routes/api.php
index e23475b..d936b96 100644
--- a/tests/Support/Routes/api.php
+++ b/tests/Support/Routes/api.php
@@ -7,6 +7,7 @@ Route::group(['as' => 'api.', 'prefix' => 'api'], function () {
     \Lomkit\Rest\Facades\Rest::resource('searchable-models', \Lomkit\Rest\Tests\Support\Http\Controllers\SearchableModelController::class);
     \Lomkit\Rest\Facades\Rest::resource('model-hooks', \Lomkit\Rest\Tests\Support\Http\Controllers\ModelHooksController::class)->withSoftDeletes();
     \Lomkit\Rest\Facades\Rest::resource('model-withs', \Lomkit\Rest\Tests\Support\Http\Controllers\ModelWithController::class);
+    \Lomkit\Rest\Facades\Rest::resource('model-with-default-limit', \Lomkit\Rest\Tests\Support\Http\Controllers\ModelWithDefaultLimitController::class);
     \Lomkit\Rest\Facades\Rest::resource('no-relationship-authorization-models', \Lomkit\Rest\Tests\Support\Http\Controllers\NoRelationshipAuthorizationModelController::class);
 
     \Lomkit\Rest\Facades\Rest::resource('no-exposed-fields', \Lomkit\Rest\Tests\Support\Http\Controllers\NoExposedFieldsController::class);