> ## Documentation Index
> Fetch the complete documentation index at: https://www.nestjs-query.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# DTOs

> REST DTOs describe response serialization, request validation, OpenAPI schemas, identifiers, and the fields accepted as filters. Their decorators combine metadata from class-transformer, class-validator, and @nestjs/swagger.

## `@Field`[​](#field "Direct link to field")

Use `@Field` for properties exposed in request or response schemas. The decorator infers primitive types from TypeScript metadata and accepts Swagger property options such as `description`, `example`, `nullable`, `minLength`, `maxLength`, `minimum`, `maximum`, and `enum`.

```ts todo-item-input.dto.ts theme={null}
import { Field } from '@ptc-org/nestjs-query-rest'

export class TodoItemInputDTO {
  @Field({ description: 'A short task title', maxLength: 100 })
  title!: string

  @Field({ default: false })
  completed!: boolean
}
```

For nested objects and arrays, provide an explicit return type:

```ts theme={null}
export class LabelDTO {
  @Field()
  name!: string
}
export class TodoItemDTO {
  @Field(() => [LabelDTO])
  labels!: LabelDTO[]
}
```

### Automatic validation

`@Field` adds the following `class-validator` decorators. Enable Nest's [request transformation and validation](https://www.nestjs-query.dev/rest/getting-started.md#enable-request-transformation-and-validation) with `ValidationPipe({ transform: true })` to apply them to incoming requests.

| Field type or option | Validation added |
| - | - |
| Required field (the default) | `IsNotEmpty()` rejects `undefined`, `null`, and `''`. It allows `0`, `false`, and empty arrays. |
| `nullable: true`, a defined `default`, or `required: false` | `IsOptional()` skips all validators on the property when its value is `undefined` or `null`. |
| `String` | `IsString()` |
| `Number` | `IsNumber()` |
| `Boolean` | `IsBoolean()` |
| `Date` | `IsDate()` |
| Explicit array type, such as `() => [String]` | `IsArray()`, plus type validation for each element. |
| Nested DTO supplied through a return type function or Swagger type metadata | `ValidateNested()`, plus `IsObject()` for a non-array field. Arrays validate each nested element. |
| `enum` | `IsEnum(enum)`, applied to each element for arrays. |
| `minLength` / `maxLength` | `MinLength(minLength)` / `MaxLength(maxLength)` |
| `minimum` / `maximum` | `Min(minimum)` / `Max(maximum)` |
| `minItems` / `maxItems` on an array field | `ArrayMinSize(minItems)` / `ArrayMaxSize(maxItems)` |

Set `nullable: true` on optional update properties. An explicit `required` option overrides the required/optional behavior inferred from `nullable` and `default`. A `default` documents the default and supplies a Swagger example; it does not assign a value to the DTO property at runtime.

Use these options to customize the automatic behavior:

* `skipRequired: true` omits both `IsNotEmpty()` and `IsOptional()`. Other validators still run, including on missing values.
* `skipIsEnum: true` omits `IsEnum()`. Type and other validators still apply.
* `forceArray: true` wraps a non-null scalar in an array before validation when the return type is an array. Without it, `IsArray()` rejects scalar input.

The type, enum, and nested validators use `each: true` for arrays. The length and numeric-bound validators do not; add your own `class-validator` decorators with `{ each: true }` when you need those constraints on individual elements. To require a nonempty array, use `minItems: 1`.

Validation runs on transformed values. The decorator adds `class-transformer`'s `Type()` for resolved types other than `Boolean`, so numeric strings and date strings can become numbers and `Date` instances before validation. Boolean fields explicitly convert the strings `'true'` and `'false'` to booleans.

Other Swagger options describe the schema without necessarily adding runtime checks. Add decorators such as `@IsEmail()`, `@IsUUID()`, or `@Matches()` when you need those validations; setting `format` or `pattern` alone does not add them.

## `@FilterableField`[​](#filterablefield "Direct link to filterablefield")

`@FilterableField` includes the property in the schema just like `@Field` and exposes it as an equality query parameter on collection and export endpoints.

```ts todo-item.dto.ts theme={null}
import { Field, FilterableField, IDField } from '@ptc-org/nestjs-query-rest'

export class TodoItemDTO {
  @IDField()
  id!: number

  @FilterableField()
  title!: string

  @FilterableField()
  completed!: boolean

  @Field()
  created!: Date
}
```

The DTO above accepts requests such as:

```http theme={null}
GET /todo-items?completed=false&title=Write%20docs
```

Additional filter options include:

* `filterRequired: true` makes the query parameter mandatory whenever the generated filter is used.
* `filterOnly: true` accepts the property as a filter but excludes it from serialized response fields.
* `filterDecorators` applies additional decorators to the generated query property.
* Standard `Field`/Swagger options control transformation and validation.

```ts theme={null}
export class TodoItemDTO {
  @FilterableField({ filterRequired: true })
  tenantId!: string

  @FilterableField({ filterOnly: true })
  internalStatus!: string
}
```

## `@IDField`[​](#idfield "Direct link to idfield")

`@IDField` identifies the property used by `GET`, `PUT`, and `DELETE` single-record routes. Declare it on the response DTO so the generated `:id` parameter is transformed to the correct type.

```ts theme={null}
export class TodoItemDTO {
  @IDField()
  id!: number
}
```

Use `idOnly: true` when an identifier should be accepted as a route parameter but omitted from generated mutation bodies.

## `@QueryOptions`[​](#queryoptions "Direct link to queryoptions")

Use `@QueryOptions` to set collection defaults on the DTO. Endpoint-level options override decorator options.

```ts theme={null}
import { SortDirection } from '@ptc-org/nestjs-query-core'
import { FilterableField, IDField, PagingStrategies, QueryOptions } from '@ptc-org/nestjs-query-rest'

@QueryOptions({
  pagingStrategy: PagingStrategies.OFFSET,
  defaultResultSize: 20,
  maxResultsSize: 100,
  defaultSort: [{ field: 'created', direction: SortDirection.DESC }],
  enableTotalCount: true
})
export class TodoItemDTO {
  @IDField()
  id!: number

  @FilterableField()
  created!: Date
}
```

See [filtering](https://www.nestjs-query.dev/rest/queries/filtering.md) and [paging](https://www.nestjs-query.dev/rest/queries/paging.md) for the generated HTTP API.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.