Fields
The fields API is split into small classes and controller helpers. Most endpoints should use ResourceQuery or prepareFieldsQuery; use the low-level classes when you need fine-grained control.
Resource Facade
const result = await ResourceQuery.query({
service: this.usersService,
query,
schema: UserDTO,
ability: req.ability,
map: (user, ability) => UserDTO.fromModel(user, ability),
});schema accepts either a manual FieldSchema or a Swagger-decorated DTO class. The helper:
- parses and validates
query.fields. - merges endpoint-required includes, client includes, and generated relation includes into a query copy.
- calls
service.queryorservice.findById. - maps models to DTOs, including async mappers.
- applies
Fields.projectto the mapped DTO response. Paginated responses can project either item fields (fields=id,titleorfields={id,title}) or the response envelope (fields=items{id,title},meta{page,perPage}). An explicit empty selection (fields=orfields={}) returns an empty envelope;items{}can intentionally return empty item objects.
prepareFieldsQuery
const prepared = prepareFieldsQuery(query, UserDTO, {
baseInclude: {
organization: true,
},
});
await usersService.query(prepared.query, ability);
Fields.project(dtoItems, prepared.projection);prepareFieldsQuery does not mutate the original query object. baseInclude is useful when the endpoint, CASL-aware mapper, or response policy needs relations even when the client omits fields; the client include query parameter extends that include object.
Low-Level Flow
const projection = FieldsParser.parse(query.fields);
if (projection) {
FieldsValidator.validateProjection(projection, userSchema);
}
const include = projection ? Fields.include(projection, userSchema, query.include) : query.include;
const response = FieldsProjector.project(dtoItems, projection);Manual Field Schema
import { relation, type FieldSchema } from '@querry-kit/nest/fields';
const schema: FieldSchema = {
id: true,
email: true,
profile: relation({
firstName: true,
lastName: true,
}),
};Decorators and Errors
Use ApiResourceQuery() for list endpoints that expose fields, page, perPage, select, include, where, orderBy, and distinct. Use ApiFieldsQuery() for detail or mutation endpoints that only expose response projection. Use @FieldsQuery(DTO) when a controller parameter should receive a validated FieldsProjection.
@Get()
@ApiFieldsQuery()
async find(@FieldsQuery(UserDTO) fields?: FieldsProjection) {}Register FieldsExceptionFilter globally when invalid fields values should produce structured HTTP 400 responses.