Introduction
What nestjs-rest-query is and why to use it.
nestjs-rest-query is a NestJS library that builds TypeORM SelectQueryBuilder instances dynamically from HTTP query parameters — filters, sorts, pagination, field selection, and relation loading — all controlled by a per-endpoint security whitelist.
Main flow
Rendering Mermaid diagram...
Each endpoint declares its own whitelist via @ApiDynamicQuery (with OpenAPI) or @DynamicQuery (without it). At runtime, QueryBuilderService validates the received parameters against that whitelist, applies each handler, and returns the already paginated result.
Features
- Dynamic filters — filter by any allowed field using operators like
eq,like,in,between,isNull, and more - Sorts — multi-column sorting with
ASC/DESC, controlled per endpoint - Pagination — page-based or limit/offset, with
page,perPage,total, andlastPageat the top of the response - Field selection — return only the columns the client needs
- Relation loading — load TypeORM relations declared in your whitelist
- Security whitelist — the
@ApiDynamicQuery/@DynamicQuerydecorators define exactly which fields and operators each endpoint allows - Swagger integration —
@ApiDynamicQueryautomatically generates@ApiQuerydecorators for all supported query parameters - Fully typed — written in TypeScript, with complete type definitions
How it works
- Decorate your controller method with
@ApiDynamicQuery(rules)(or@DynamicQuery(rules)) - Add
@QueryRules()as a parameter decorator to receive the rules at runtime - Call
queryBuilderService.execute(repo, query, rules)— the library applies filters, sorts, pagination, and relations, returning the results with pagination data at the top of the response
@Get()
@ApiDynamicQuery({
filters: ['name', 'status', 'createdAt'],
sorts: ['name', 'createdAt'],
includes: ['company'],
})
findAll(
@Query() query: DynamicQueryDto,
@QueryRules() rules: RulesConfig,
) {
return this.queryBuilderService.execute(this.repo, query, rules);
}