NestJS · TypeORM · Drizzle
Transforme query strings REST em queries seguras.
nestjs-rest-query dá aos endpoints NestJS filtros dinâmicos, ordenação, paginação, seleção de campos e carregamento de relations com whitelist por endpoint para TypeORM e Drizzle.
Do encanamento manual de queries para um único decorator
Cada endpoint declara os campos, sorts e operadores que aceita. A lib parseia a query string, valida contra a whitelist e executa a consulta via TypeORM ou Drizzle.
Antes — escrito à mão
@Get()
async listCompanies(@Query() query: ListCompaniesQuery) {
const qb = this.companies.createQueryBuilder('company');
if (query.name) qb.andWhere('company.name ILIKE :n', { n: `%${query.name}%` });
if (query.cnpj) qb.andWhere('company.cnpj = :c', { c: query.cnpj });
if (query.createdFrom) qb.andWhere('company.createdAt >= :f', { f: query.createdFrom });
if (query.sort === 'name') qb.orderBy('company.name', query.dir ?? 'ASC');
if (query.sort === 'createdAt') qb.orderBy('company.createdAt', query.dir ?? 'DESC');
const page = Number(query.page ?? 1);
const perPage = Math.min(Number(query.perPage ?? 20), 100);
qb.skip((page - 1) * perPage).take(perPage);
const [data, total] = await qb.getManyAndCount();
return { data, page, perPage, total, lastPage: Math.ceil(total / perPage) };
}Depois — nestjs-rest-query
@Get()
@ApiDynamicQuery<Company>({
filters: ['name', 'cnpj', 'createdAt'],
sorts: ['name', 'createdAt'],
fields: ['id', 'name', 'cnpj', 'createdAt'],
})
findAll(@Query() query: QueryInput, @QueryRules() rules: RulesConfig) {
return this.qb.execute(this.companies, query, rules);
}Compatibilidade de adapters
TypeORM e Drizzle são estáveis. Prisma está no roadmap e usará os mesmos decorators e o mesmo contrato de whitelist.
| Adapter | Status | Notas |
|---|---|---|
| TypeORM | Estável | Adapter padrão, construído sobre SelectQueryBuilder. |
| Drizzle | Estável | Ativado via DrizzleAdapter, com mapa explícito de relations. |
| Prisma | Roadmap | Planejado. Mesmos decorators, motor diferente. |
Quickstart
- 1Instalar
Adicione o pacote ao seu app NestJS.
pnpm add nestjs-rest-query - 2Registrar o módulo
Importe o DynamicQueryBuilderModule uma vez, no AppModule.
import { DynamicQueryBuilderModule } from 'nestjs-rest-query'; @Module({ imports: [DynamicQueryBuilderModule.forRoot()], }) export class AppModule {} - 3Declarar a whitelist
Cada endpoint declara quais campos, sorts e includes os clientes podem usar.
@Get() @ApiDynamicQuery<Company>({ filters: ['name', 'cnpj', 'createdAt'], sorts: ['name', 'createdAt'], }) findAll(@Query() q: QueryInput, @QueryRules() rules: RulesConfig) { return this.qb.execute(this.companies, q, rules); }