заморачивается? при чём в контексте чистого js, не ts.
я вот хочу данные между сервисами гонять в виде какой-то готовой провалидированной структуры. понаписал тут вот такое:
import assert from 'assert';
export default class BaseDTO {
static schema;
static validateByScheme(data, schema) {
// validate by `ajv`
// `throw new ValidationError()` if data is invalid
}
constructor(data) {
const { schema, validateByScheme } = this.constructor;
assert(schema, 'Schema is not defined');
validateByScheme(data, schema);
Object.assign(this, data);
}
toJSON() {
return { ...this };
}
}
ну и от BaseDTO можно отнаследоваться, например вот так:
class UserDTO extends BaseDTO {
static schema = {
type: 'object',
properties: {
firstName: { type: 'string' },
lastName: { type: 'string' },
},
};
get fullName() {
return `${this.firstName} ${this.lastName}`;
}
toJSON() {
const { fullName } = this;
return {
...super.toJSON(),
fullName,
};
}
}
т.е. в унаследованном классе прописываем схему, можно даже свою реализацию validateByScheme (например, для валидации Joi-ем, а не ajv), можно какие-то геттеры добавить и, если надо, эти геттеры подставить в результат toJSON'а.
Работает как-то так:
const user = new UserDTO({
firstName: 'Pampampam',
lastName: 'Pumpumpum',
});
console.log('user', JSON.stringify(user, null, 2));
/*
user {
"firstName": "Pampampam",
"lastName": "Pumpumpum",
"fullName": "Pampampam Pumpumpum"
}
*/
В принципе, на первый взгляд выглядит более-менее.
Плюсы вижу такие:
1. такие dto можно инстанцировать прямо в контроллерах, что-то типа
new FiltersDTO(req.query)
или
new SearchFormDTO(req.body)
и, если данные неправильные, то ошибка отловится в мидлваре и клиенту уйдёт ответ с ошибками валидации и соответствующим http-кодом. А если данные по схеме прошли, то спокойно этот объект отдавать дальше во внутренние сервисы, в которых единственная необходимая проверка - это что-то типа такого:
class UsersService {
/**
* @param {UserDTO} user
*/
constructor(user) {
assert(user instanceof UserDTO);
this.user = user;
}
// someMethod() {}
}
2. из этих схем когда-нибудь потом можно будет прикрутить генерацию документации к api.
Минусов на первый взгляд не вижу. Но поэтому вам сюда и пишу) Может есть какие-то подводные камни, которые прямо сейчас лично мне неочевидны?
Такой подход вообще норм?
Схема должна быть отдельно от dto. В dto только поля с данными
как же все сложно
Обсуждают сегодня