QueryOptions
The @QueryOptions() decorator allows you to configure the default behavior of queries for a specific DTO class. This includes pagination strategy, result sizes, default sorting, filtering options, and connection settings.
Overview
Section intitulée « Overview »The @QueryOptions() decorator is applied to a DTO class and affects all queries generated for that class. It provides a way to set defaults and enable/disable features at the DTO level, rather than having to specify them for each query.
Basic Usage
Section intitulée « Basic Usage »Apply the decorator to your DTO class:
import { ObjectType, Field } from '@lib/type-graphql';import { QueryOptions, PagingStrategies } from '@lib/type-graphql-query';
@ObjectType()@QueryOptions({ pagingStrategy: PagingStrategies.OFFSET, maxResultsSize: 100, defaultSort: [{ field: 'createdAt', direction: SortDirection.DESC }],})export class Product { @Field() id!: string;
@Field() name!: string;
@Field() createdAt!: Date;}Pagination Strategy
Section intitulée « Pagination Strategy »The pagingStrategy option determines how results are paginated:
PagingStrategies.CURSOR(default): Cursor-based pagination usingfirst/lastandbefore/aftercursorsPagingStrategies.OFFSET: Offset-based pagination usinglimitandoffsetPagingStrategies.NONE: No pagination, returns a simple array
@QueryOptions({ pagingStrategy: PagingStrategies.OFFSET, // Use offset pagination})Result Size
Section intitulée « Result Size »Control the default and maximum number of results:
@QueryOptions({ defaultResultSize: 20, // Default number of results (default: 10) maxResultsSize: 100, // Maximum number of results (default: 50) // Use -1 for unlimited results maxResultsSize: -1, // No limit})Default Sorting
Section intitulée « Default Sorting »Set the default sort order for queries:
import { SortDirection } from "@lib/type-graphql-query";
@QueryOptions({ defaultSort: [ { field: 'createdAt', direction: SortDirection.DESC }, { field: 'name', direction: SortDirection.ASC }, ],})Enable/Disable Features
Section intitulée « Enable/Disable Features »Control which query features are available:
@QueryOptions({ enableSort: true, // Enable sorting (default: true) enableFilter: true, // Enable filtering (default: true) enableFetchAllWithNegative: true, // Allow negative limits to fetch all (default: false)})Default Filter
Section intitulée « Default Filter »Apply a default filter to all queries:
@QueryOptions({ defaultFilter: { status: { eq: 'active' }, },})Filter Options
Section intitulée « Filter Options »Configure filter behavior:
@QueryOptions({ allowedBooleanExpressions: ['and', 'or'], // Allowed boolean operators (default: ['and', 'or']) filterDepth: 2, // Maximum depth for nested filters (default: 1)})Connection Options
Section intitulée « Connection Options »Configure connection behavior (applies to cursor and offset pagination):
@QueryOptions({ pagingStrategy: PagingStrategies.CURSOR, enableTotalCount: true, // Include totalCount in connection (default: false) connectionName: 'ProductConnection', // Custom connection name enableAggregate: true, // Enable aggregate queries})Keyset pagination is enabled automatically when the DTO declares @KeySetField on one or more properties.
Examples
Section intitulée « Examples »Offset Pagination with Unlimited Results
Section intitulée « Offset Pagination with Unlimited Results »@ObjectType()@QueryOptions({ pagingStrategy: PagingStrategies.OFFSET, maxResultsSize: -1, // No limit})export class Permission { @Field() id!: string;
@Field() name!: string;
@Field() order!: number;}Cursor Pagination with Default Sort
Section intitulée « Cursor Pagination with Default Sort »@ObjectType()@QueryOptions({ pagingStrategy: PagingStrategies.CURSOR, defaultResultSize: 20, maxResultsSize: 100, defaultSort: [{ field: 'name', direction: SortDirection.ASC }], enableTotalCount: true,})export class Category { @Field() id!: string;
@Field() name!: string;}No Pagination with Default Filter
Section intitulée « No Pagination with Default Filter »@ObjectType()@QueryOptions({ pagingStrategy: PagingStrategies.NONE, defaultFilter: { isActive: { eq: true }, }, enableFilter: true,})export class Status { @Field() id!: string;
@Field() name!: string;
@Field() isActive!: boolean;}Complex Configuration
Section intitulée « Complex Configuration »@ObjectType()@QueryOptions({ pagingStrategy: PagingStrategies.OFFSET, defaultResultSize: 25, maxResultsSize: 200, defaultSort: [ { field: 'priority', direction: SortDirection.DESC }, { field: 'createdAt', direction: SortDirection.DESC }, ], enableSort: true, enableFilter: true, enableFetchAllWithNegative: false, defaultFilter: { status: { eq: 'published' }, }, allowedBooleanExpressions: ['and', 'or'], filterDepth: 3, enableTotalCount: true, connectionName: 'ProductConnection',})export class Product { @Field() id!: string;
@Field() name!: string;
@Field() status!: string;
@Field() priority!: number;
@Field() createdAt!: Date;}Complete Options Reference
Section intitulée « Complete Options Reference »Base Options (All Strategies)
Section intitulée « Base Options (All Strategies) »| Option | Type | Default | Description |
|---|---|---|---|
defaultResultSize |
number |
10 |
Default number of results to return |
maxResultsSize |
number |
50 |
Maximum number of results (-1 for unlimited) |
defaultSort |
SortField<DTO>[] |
[] |
Default sort order |
enableSort |
boolean |
true |
Enable sorting feature |
defaultFilter |
Filter<DTO> |
{} |
Default filter to apply |
enableFilter |
boolean |
true |
Enable filtering feature |
enableFetchAllWithNegative |
boolean |
false |
Allow negative limits to fetch all |
allowedBooleanExpressions |
('and' | 'or')[] |
['and', 'or'] |
Allowed boolean operators |
filterDepth |
number |
1 |
Maximum depth for nested filters |
Cursor Pagination Options
Section intitulée « Cursor Pagination Options »| Option | Type | Default | Description |
|---|---|---|---|
pagingStrategy |
PagingStrategies.CURSOR |
- | Use cursor-based pagination |
enableTotalCount |
boolean |
false |
Include totalCount in connection |
connectionName |
string |
Auto-generated | Custom connection name |
enableAggregate |
boolean |
false |
Enable aggregate queries |
AggregateDTOClass |
ClassType<object> |
- | DTO class for aggregate results |
Offset Pagination Options
Section intitulée « Offset Pagination Options »| Option | Type | Default | Description |
|---|---|---|---|
pagingStrategy |
PagingStrategies.OFFSET |
- | Use offset-based pagination |
enableTotalCount |
boolean |
false |
Include totalCount in connection |
connectionName |
string |
Auto-generated | Custom connection name |
enableAggregate |
boolean |
false |
Enable aggregate queries |
AggregateDTOClass |
ClassType<object> |
- | DTO class for aggregate results |
No Pagination Options
Section intitulée « No Pagination Options »| Option | Type | Default | Description |
|---|---|---|---|
pagingStrategy |
PagingStrategies.NONE |
- | No pagination, return array |
enableAggregate |
boolean |
false |
Enable aggregate queries |
AggregateDTOClass |
ClassType<object> |
- | DTO class for aggregate results |
Best Practices
Section intitulée « Best Practices »-
Choose the Right Pagination Strategy
- Use
CURSORfor large datasets and when you need stable pagination - Use
OFFSETfor simpler use cases and when you need page numbers - Use
NONEfor small, fixed-size datasets
- Use
-
Set Reasonable Limits
- Always set
maxResultsSizeto prevent accidental large queries - Use
-1only when you’re certain the dataset is manageable
- Always set
-
Use Default Filters for Security
- Apply default filters to automatically exclude soft-deleted or inactive records
- Combine with
@ContextFilterfor row-level security
-
Optimize with Default Sorting
- Set default sorting to match your most common query patterns
- This can improve database query performance
-
Control Filter Depth
- Limit
filterDepthto prevent overly complex queries - Higher depths can impact performance
- Limit
Integration with Other Decorators
Section intitulée « Integration with Other Decorators »The @QueryOptions() decorator works in conjunction with other decorators:
@ContextFilter(): Default filters from@QueryOptionsare combined with filters from@ContextFilter@EnhancedField(): Field-level options (likefilterable,sortable) are respected by query options@Authorize(): Authorization rules apply regardless of query options
See Also
Section intitulée « See Also »- Queries Overview - Learn about query endpoints
- Filtering - Understand filtering options
- Paging - Learn about pagination strategies
- Sorting - Understand sorting options
- ContextFilter - Automatic filtering decorator