DTO
General
DTO(Data Transfer Object) is used for parsing and validating data from request. DTOs always used with Controllers.
Validation
It's a common scenario when web server should validate data before processing. DTO can optimize and automate this process.
Overview
Let's imagine that we need to implement this API.
Accepts application/json
in following format:
With following limitations:
title
- required, max length - 80 chars.description
- optional, max length - 255 chars.
Let's start from DTO class
And controller with some predefined service
Data from request body will be automatically injected and validated. If validation failed - errors will be automatically sent to client.
DTO definition
Currently, there are two types of DTO, for querystring
and body
validation.
Decorators
@Data()
- set DTO for handlingbody
@Query()
- set DTO for handlingquerystring
Handler Injection
There are no additional actions required for including DTO in the handler (method of the controller). Just add DTO (or multiple) as an argument.
Decorators for validation
There are set of decorators for convenient data validation. If you have special needs on validation, you can always implement your own decorator (read more in advanced). But custom decorators can be implemented. Read in Advanced about it.
Decorators can be grouped by data type
General
This decorators can be applied to any type of data.
@IsOptional()
- set field optional (by default, all fields are required)@Const(value: any)
- field is valid if it is deeply equal to the passed value@Deafault(value: any)
- default value for field, if it not exists@Enum(enumrable: any[])
- data is valid if it is deeply equal to one of items in the array@Nested()
- validate nested DTO class, otherwise field will be ignored
Decorator @Nested
should be applied on field, which type is DTO class.
String
@MaxLength(maxLength: number)
- data to be valid should have length satisfying this rule@MinLength(minLength: number)
- data to be valid should have length satisfying this rule@Pattern(pattern: string | RegExp)
- data to be valid should match the regular expression@Format(format: ValidatorFormat)
- data to be valid should match the format@IsEmail()
- data to be valid should be email (Format
alias)@IsUrl()
- data to be valid should be url (Format
alias)
Following formats for @Format
decorator available:
Number
@Maximum(maximum: number)
- data to be valid should be<=
maximum@Minimum(minimum: number)
- data to be valid should be>=
minumum@ExclusiveMaximum(exclusiveMaximum: number)
- data to be valid should be<
maximum@ExclusiveMinimum(exclusiveMinimum: number)
- data to be valid should be>
minimum@MultipleOf(multipleOf: number)
- data to be valid should be a multiple of themultipleOf
Array
@ArrayOf(targetClass: any)
- sets type of array items@UniqueItems()
- array to be valid should have unique items@MaxItems(maxItems: number)
- array to be valid should not have less items than themaxItems
@MinItems(minItems: number)
- array to be valid should not have more items than theminItems
@ArraoyOf
can be used only if array item type is another DTO class. As typescript does not provide reflection for complex types, type should be setted manually.
Others
@CustomValidation(validate: ValidateFunction, params: any = true)
- define custom validation function for field. Validate function can be async.
Transformation
Data transformation from plain object to DTO instance applied automatically. But don't forget about @ArraoyOf
decorator for DTOs arrays.
Inheritance
You can easily use inheritance (extends)
for DTOs.
TodoDTO
will inherit all properties from base class for both transformation and validation purposes.
Flow
Every controller method that contains DTO class as argument will be automatically provided with validated and mapped data. Validation will be performed before controller method call.
Only after transformation, DTO will be injected into method call. Under the hood ajv is used. Decorators is used to build schema.
Last updated