Getting Started
This guide shows how to install @querry-kit/nest-fields-query, create field schemas, validate fields query values, and apply projections to response DTOs.
Installation
Install the package from npm:
pnpm add @querry-kit/nest-fields-query@querry-kit/nest-fields-query uses object helpers from @querry-kit/nest-util. Install it explicitly when your package manager does not install regular dependencies automatically:
pnpm add @querry-kit/nest-fields-query @querry-kit/nest-utilGitHub release tags remain available as a fallback. The main branch contains source only; release tags contain the built dist files required by Node.js.
pnpm add github:querry-kit/nest-fields-query#vX.Y.ZTypeScript ESM
This package is ESM-first. In TypeScript projects that emit ESM, keep relative local imports explicit with .js extensions.
Create a Field Schema
Use Swagger-decorated DTOs when your response DTOs already describe the public response shape:
import { ApiProperty } from '@nestjs/swagger';
import { buildFieldSchemaFromDto } from '@querry-kit/nest-fields-query';
class ProfileDTO {
@ApiProperty()
firstName!: string;
}
class UserDTO {
@ApiProperty()
id!: string;
@ApiProperty({ type: () => ProfileDTO })
profile!: ProfileDTO;
}
const userSchema = buildFieldSchemaFromDto(UserDTO);Manual schemas are useful when a route exposes a custom shape:
import { relation } from '@querry-kit/nest-fields-query';
const userSchema = {
id: true,
email: true,
profile: relation({
firstName: true,
lastName: true,
}),
};Use Fields in Controllers
Parse and validate the raw query value with FieldsQuery before calling the service. Use Fields.include when selected relation fields need to be included in the query result.
import { Controller, Get, Query } from '@nestjs/common';
import { Fields, FieldsProjection, FieldsQuery, buildFieldSchemaFromDto } from '@querry-kit/nest-fields-query';
const userSchema = buildFieldSchemaFromDto(UserDTO);
@Controller('users')
export class UsersController {
@Get()
async findMany(
@Query() query: { include?: unknown },
@FieldsQuery(UserDTO) fields?: FieldsProjection,
) {
const include = fields ? Fields.include(fields, userSchema, query.include) : query.include;
const items = await this.usersService.findMany({ ...query, include });
const dtoItems = items.map(UserDTO.fromModel);
return Fields.project(dtoItems, fields);
}
}@FieldsQuery(DTO) derives its validation schema from Swagger metadata, so selectable DTO properties must be decorated with @ApiProperty or compatible Swagger metadata.
Register the Exception Filter
Register FieldsExceptionFilter globally when invalid fields query parameters should produce a structured HTTP 400 response:
import { FieldsExceptionFilter } from '@querry-kit/nest-fields-query';
app.useGlobalFilters(new FieldsExceptionFilter());Example API
The repository includes a small books and authors NestJS API under examples/books-api. It follows the same controller flow shown above, including DTO-backed schemas, generated includes, service calls, DTO mapping, and response projection.
GET Request Example
For the books example, a client can request a nested author projection like this:
GET /books?fields=id,title,author{name,books{title}}The same request in a Bruno-style environment usually keeps the base URL in a variable and lists query parameters explicitly:
GET {{host}}/api/v1/books?fields=id,title,author{name,books{title}}
Query Params:
fields: id,title,author{name,books{title}}When an endpoint validates that selected relations are also present in the incoming include query, use bracket notation for explicit includes:
GET {{host}}/api/v1/books?fields=id,title,author{name,books{title}}&include[author][include][books]=true
Query Params:
fields: id,title,author{name,books{title}}
include[author][include][books]: trueRuntime Expectations
FieldsParseraccepts strings such asid,email,profile{firstName}.- Empty,
null, orundefinedvalues returnundefined. - Invalid syntax throws
FieldsBadRequestException. FieldsValidatorrejects unknown fields and nested selections on scalar schema nodes.Fields.includepreserves existing include configuration and normalizes dotted include keys through@querry-kit/nest-util.Fields.projectworks with objects, arrays, primitives,null, andundefined.
Minimal Verification
After installation, add a small controller or utility test:
import { Fields, relation } from '@querry-kit/nest-fields-query';
it('projects selected fields', () => {
const schema = { id: true, profile: relation({ firstName: true }) };
const projection = Fields.parseAndValidate('id,profile{firstName}', schema);
expect(Fields.project({ id: '1', profile: { firstName: 'Ada', lastName: 'Lovelace' } }, projection)).toEqual({
id: '1',
profile: { firstName: 'Ada' },
});
});