Intent.Application.Dtos.Pagination
What is Pagination?
Pagination constrains large result sets into manageable slices, improving performance and user experience by loading data incrementally. This module generates DTO result wrappers and mapping helpers for both offset-based and cursor-based pagination patterns.
Intent Architect supports two pagination strategies:
- Offset-based pagination (
PagedResult<T>) - Traditional page number and page size approach with total counts - Cursor-based pagination (
CursorPagedResult<T>) - Token-based approach for efficient pagination of dynamic datasets
What This Module Generates
PagedResult (Offset-based)
A generic DTO wrapper with the following properties:
TotalCount- Total number of items across all pagesPageCount- Total number of pages availablePageSize- Number of items per pagePageNumber- Current page number (1-indexed)Data- Collection of items for the current page
CursorPagedResult (Cursor-based)
A generic DTO wrapper with the following properties:
Data- Collection of items for the current pageCursorToken- Opaque token to retrieve the next pagePageSize- Number of items requested per pageHasMoreResults- Boolean indicating if more pages are available (derived from CursorToken presence)
Mapping Extensions
Helper extension methods to map repository/query results into paginated DTOs, reducing boilerplate in service handlers.
Type Source Installer
Registers pagination types with the application layer for use in Services Designer modeling.
Examples
Example: Offset-based Pagination (PagedResult)
// Query Handler with PagedResult
public class GetCustomersQueryHandler : IRequestHandler<GetCustomersQuery, PagedResult<CustomerDto>>
{
private readonly ICustomerRepository _repository;
public async Task<PagedResult<CustomerDto>> Handle(GetCustomersQuery request, CancellationToken cancellationToken)
{
// Repository returns IPagedList<Customer> from EF Core
var pagedCustomers = await _repository.FindAllAsync(
request.PageNumber,
request.PageSize,
cancellationToken);
// MapToPagedResult is an Intent-generated extension method
return pagedCustomers.MapToPagedResult(customer => customer.MapToCustomerDto());
}
}
// API Response
{
"totalCount": 1523,
"pageCount": 16,
"pageSize": 100,
"pageNumber": 1,
"data": [
{ "id": 1, "name": "Acme Corp" },
{ "id": 2, "name": "Beta Industries" }
// ... 98 more items
]
}
Example: Cursor-based Pagination (CursorPagedResult)
public async Task<CursorPagedResult<CustomerDto>> GetCustomers(string? after, int size)
{
var query = _dbContext.Customers.OrderBy(c => c.Id);
return await query.ProjectTo<CustomerDto>(_mapper.ConfigurationProvider)
.ToCursorPagedResultAsync(after, size); // intent-generated extension
}
When to Use PagedResult vs CursorPagedResult
Often this is limited to the persistence technology you have chosen. However here are some things to consider:
Use PagedResult (Offset-based) when:
- Users need to jump to specific page numbers (e.g., "Go to page 5")
- You need to display total count and page count in the UI
- The dataset is relatively stable (infrequent inserts/deletes)
- Implementing traditional table pagination with page number selectors
- Dataset size is moderate (thousands, not millions)
Use CursorPagedResult (Cursor-based) when:
- Dealing with real-time or frequently changing data (e.g., social feeds, logs)
- Implementing infinite scroll patterns in the UI
- Optimizing performance for very large datasets (millions of rows)
- Preventing duplicate or skipped items during pagination
- Users only need "next page" functionality (no arbitrary page jumping)
- Working with distributed systems where consistent counts are expensive
Integration with Other Modules
- Works with
Intent.Application.Dtosbase DTO infrastructure. - Commonly combined with repositories (Entity Framework, MongoDb, CosmosDb, Redis) through LINQ queries.
- Complements
Intent.Application.ServiceImplementationsor CQRS-based query handlers (Intent.MediatR).
Intent-Specific Patterns
- Extensions encapsulate converting a query into the correct wrapper reducing repetition.
- DTO wrapping enforces consistent API responses and allows future augmentation (e.g., including server timing).
Pagination Defaults
Default values for all paginated queries and operations can be configured on the Application Settings screen.
If either of the pagination defaults is set, pageNo will automatically default to 1.
- Page Size Default – The default page size applied to all paged services.
- Order By Default – The default sort (order by) applied to all paged services.
If the service is exposed as an HTTP endpoint, these defaults are also applied to the controller and will be visible in the generated OpenAPI documentation.
Note: These defaults can be overridden on a specific
QueryorService Operationby explicitly setting thepageNo,pageSize, ororderByfield/parameter.
Related Modules
- Intent.Application.Dtos - Base DTO infrastructure
- Intent.Entities.Repositories.Api - Repository patterns with pagination support
- Intent.EntityFrameworkCore - Entity Framework implementation with pagination
- Intent.MongoDb - MongoDB repositories with pagination
- Intent.CosmosDB - Cosmos DB repositories with pagination
- Intent.Application.MediatR - CQRS query handlers that return paginated results