Task is to validate payload in nest.js app before managing one.
Each payload can contain tag objects (1 - 11).
Every tag object can have only one property and value (property determined by request)
Tag objects should be validated:
- property should be a string with any characters accept
:and size in 1-255 - value should be a string with size in 1-255
Task looks like simple one. But I have no idea how to validate dynamically constructed properties in Tag objects.
The DTOs are (validation configured using class-validator):
import {
ArrayMaxSize,
ArrayMinSize,
IsArray,
IsDefined,
IsNotEmpty,
IsObject,
IsString,
Matches,
MinLength,
ValidateNested
} from 'class-validator';
export class Payload {
...
@IsArray()
@ArrayMinSize(1)
@ArrayMaxSize(11)
@ValidateType(() => Tag)
@ValidateNested()
@ApiProperty()
tags: Tag[];
}
To make Tag flexible (because unknown property name) it made like Map extension
export class Tag extends Map<string, string>{
}
or single field object
export class Tag {
[key: string]: string;
}
How to manage required validation for each Tag?
(Regexp that excludes input with : is /^[^:]+$/ and should be applied for key)
I've got solution, but better than solution implementation compare possible approaches.
1 scenario is to put additional custom validation decorators on
tagsfieldit might be good solution. Following this way we'd realise that decorator names do not bring enough information. Trying to make them more universal we can add more parameters. But this improvements can't change the fact that we ave validating not current or next level property. We do validation of property on next after next level (
tags[]->Tag->theProperty).2 scenrio is to manage validation on middleware layer. It might bring some difficulties if you want make reports same format and after similar flow as provided in
class-validatorbut benefit is that we can spit validations on different methods constructing more complex validation tree. Also it would be easy for testing.3 scenrio is to decline dynamic property names (if that's possible) and consider developing alternative model like
it gives us chance using provided decorators from
class-validatorfor our needs, for exampleP.S.
I've managed my solution following 3rd way.