Skip to content

Commit e501631

Browse files
refactor(controller): extract EnforceStrictPagination from JsonApiQueryAsync (#128)
- Pulls the strict-pagination 404 check (19 lines) out of `JsonApiQueryAsync` into a private static helper. - No behavior change. Existing `StrictPaginationIntegrationTests` cover the path. - `JsonApiQueryAsync` shrinks from 86 to 67 lines and reads as a linear pipeline.
1 parent b639fdd commit e501631

1 file changed

Lines changed: 30 additions & 21 deletions

File tree

JsonApiToolkit/Controllers/JsonApiController.cs

Lines changed: 30 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -206,25 +206,7 @@ string resourceType
206206
int totalCount = await filteredQuery.CountAsync().ConfigureAwait(false);
207207
LogCountResults<T>(parameters, totalCount);
208208

209-
if (Options.StrictPagination && parameters.Pagination != null && totalCount > 0)
210-
{
211-
int totalPages = (int)Math.Ceiling(totalCount / (double)parameters.Pagination.Size);
212-
if (parameters.Pagination.Number > totalPages)
213-
{
214-
throw new JsonApiNotFoundException(
215-
$"Page {parameters.Pagination.Number} does not exist. "
216-
+ $"This collection has {totalPages} page(s). Request a page between 1 and {totalPages}.",
217-
JsonApiErrorCodes.InvalidPageNumber,
218-
new ErrorSource { Parameter = "page[number]" },
219-
new Dictionary<string, object>
220-
{
221-
["value"] = parameters.Pagination.Number,
222-
["totalPages"] = totalPages,
223-
["totalResources"] = totalCount,
224-
}
225-
);
226-
}
227-
}
209+
EnforceStrictPagination(Options, parameters, totalCount);
228210

229211
if (parameters.Pagination != null)
230212
filteredQuery = filteredQuery.ApplyPagination(parameters.Pagination, totalCount);
@@ -241,7 +223,7 @@ string resourceType
241223
parameters.Pagination?.Size ?? totalCount
242224
);
243225

244-
IActionResult? projectionResult = await TryApplyDatabaseProjection(
226+
IActionResult? projectionResult = await TryApplyDatabaseProjectionAsync(
245227
filteredQuery,
246228
resourceType,
247229
baseUrl,
@@ -511,6 +493,33 @@ List<string> mappedIncludes
511493
return filteredQuery;
512494
}
513495

496+
private static void EnforceStrictPagination(
497+
JsonApiOptions options,
498+
QueryParameters parameters,
499+
int totalCount
500+
)
501+
{
502+
if (!options.StrictPagination || parameters.Pagination is null || totalCount == 0)
503+
return;
504+
505+
int totalPages = (int)Math.Ceiling(totalCount / (double)parameters.Pagination.Size);
506+
if (parameters.Pagination.Number <= totalPages)
507+
return;
508+
509+
throw new JsonApiNotFoundException(
510+
$"Page {parameters.Pagination.Number} does not exist. "
511+
+ $"This collection has {totalPages} page(s). Request a page between 1 and {totalPages}.",
512+
JsonApiErrorCodes.InvalidPageNumber,
513+
new ErrorSource { Parameter = "page[number]" },
514+
new Dictionary<string, object>
515+
{
516+
["value"] = parameters.Pagination.Number,
517+
["totalPages"] = totalPages,
518+
["totalResources"] = totalCount,
519+
}
520+
);
521+
}
522+
514523
private void LogCountResults<T>(QueryParameters parameters, int totalCount)
515524
{
516525
if (totalCount == 0 && parameters.Filter?.Filters?.Count > 0)
@@ -526,7 +535,7 @@ private void LogCountResults<T>(QueryParameters parameters, int totalCount)
526535
}
527536
}
528537

529-
private async Task<IActionResult?> TryApplyDatabaseProjection<T>(
538+
private async Task<IActionResult?> TryApplyDatabaseProjectionAsync<T>(
530539
IQueryable<T> filteredQuery,
531540
string resourceType,
532541
string baseUrl,

0 commit comments

Comments
 (0)