Model
The classes can be used as a model in your application. Ts.ED use this models to convert JSON objects to theirs class equivalents.
The classes models can be used in the following cases:
- Serialization and deserialisation of data (Converters),
- Data validation with AJV,
- Generating documentation with Swagger.
To create a model, Ts.ED provides decorators who will store and generate a standard JsonSchema model.
Example
The example below uses decorators to describe a property of the class and store metadata such as the description of the field.
import {Property, Minimum} from "@tsed/common";
import {Description} from "@tsed/swagger";
class Person {
_id: string;
@Property()
firstName: string;
@Property()
lastName: string;
@Description("Age in years")
@Minimum(0)
age: number;
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
The previous example will generate the following JsonSchema:
{
"title": "Person",
"type": "object",
"properties": {
"firstName": {
"type": "string"
},
"lastName": {
"type": "string"
},
"age": {
"description": "Age in years",
"type": "number",
"minimum": 0
}
},
"required": ["firstName", "lastName"]
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
This JsonSchema can be used by all modules supporting the JsonSchema spec.
WARNING
Some of you will notice that the _id
property doesn't appear in the JsonSchema. It's very important to understand that
TypeScript only generates metadata on properties with at least one decorator.
In the case of our model, it will always be necessary that there is at least one of the decorators of the list hereafter.
Decorators
Usage
Models can be uses with the Controllers.
Here our model:
import {Property, Minimum} from "@tsed/common";
import {Description} from "@tsed/swagger";
class Person {
@Property()
firstName: string;
@Property()
lastName: string;
@Description("Age in years")
@Minimum(0)
age: number;
}
2
3
4
5
6
7
8
9
10
11
12
13
14
And its use in a controller:
import {Post, Controller, BodyParams} from "@tsed/common";
import {Person} from "../models/Person";
@Controller("/")
export class PersonsCtrl {
@Post("/")
save(@BodyParams() person: Person): Person {
console.log(person instanceof Person); // true
return person; // will be serialized according to your annotation on Person class.
}
//OR
@Post("/")
save(@BodyParams('person') person: Person): Person {
console.log(person instanceof Person); // true
return person; // will be serialized according to your annotation on Person class.
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
In this example, Person model is used both as input and output types.
JsonSchema
In some cases, it may be useful to retrieve the JSON Schema from a Model for use with another library.
Here is an example of use with the AJV library:
import * as Ajv from "ajv";
import {ErrorObject} from "ajv";
import {BadRequest} from "ts-httpexceptions";
import {OverrideService, JsonSchemesService, ValidationService} from "@tsed/common";
@OverrideService(ValidationService)
export class AjvService extends ValidationService {
constructor(private jsonSchemaService: JsonSchemesService) {
super();
}
public validate(obj: any, targetType: any, baseType?: any): void {
const schema = this.jsonSchemaService.getSchemaDefinition(targetType);
if (schema) {
const ajv = new Ajv();
const valid = ajv.validate(schema, obj);
if (!valid) {
throw(this.buildErrors(ajv.errors!));
}
}
}
private buildErrors(errors: ErrorObject[]) {
const message = errors.map(error => {
return `{{name}}${error.dataPath} ${error.message} (${error.keyword})`;
}).join("\n");
return new BadRequest(message);
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
← Provider Converters →