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.

AdapterStatusNotas
TypeORMEstávelAdapter padrão, construído sobre SelectQueryBuilder.
DrizzleEstávelAtivado via DrizzleAdapter, com mapa explícito de relations.
PrismaRoadmapPlanejado. Mesmos decorators, motor diferente.

Quickstart

  1. 1Instalar

    Adicione o pacote ao seu app NestJS.

    pnpm add nestjs-rest-query
  2. 2Registrar o módulo

    Importe o DynamicQueryBuilderModule uma vez, no AppModule.

    import { DynamicQueryBuilderModule } from 'nestjs-rest-query';
    
    @Module({
      imports: [DynamicQueryBuilderModule.forRoot()],
    })
    export class AppModule {}
  3. 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);
    }