170 похожих чатов

Народ, а над DTO (который data transfer object) вообще кто-нибудь

заморачивается? при чём в контексте чистого 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.

Минусов на первый взгляд не вижу. Но поэтому вам сюда и пишу) Может есть какие-то подводные камни, которые прямо сейчас лично мне неочевидны?
Такой подход вообще норм?

2 ответов

6 просмотров

Схема должна быть отдельно от dto. В dto только поля с данными

как же все сложно

Похожие вопросы

Обсуждают сегодня

А чем вам питонисты не угодили?😂
.
79
Dim Dim, [02.07.2024 11:07] DB 0x62 Dim Dim, [02.07.2024 11:07] DB 0x66 Dim Dim, [02.07.2024 11:07] кто пояснит что это?
Dim Dim
14
Всем привет, написал код ниже, но он выдает сегфолт, в чем причина? #include <stdio.h> #include <stdlib.h> #include <string.h> struct product { char *name; float price; };...
buzz базз
75
Язык Си можно выучить за день? По книжке ANSI C на 230 страниц
Vincent Vegan
29
Кстати, я тут еще с одной темой столкнулся, вот учу я C++, на таком то ресурсе, а остальные постоянно советуют практиковаться, что то писать, проекты, но как писать если вот т...
aaswq1
7
Ребят, а за скок можно впарить анон чат с апишкой и веб админкой ?
Eugene Неелов
15
Подскажите, можно ведь комбинировать запись данных в один и тот же Stream через TFileStream и через TCompressionStream поочерёдно? Ну т.е. часть данных мне нужно сжать, часть ...
notme
4
Ещё такой вопрос. Мне необходимо хранить пароль пользователя локально. Для этого планирую использовать ini файл. Это для автозаполнения полей логин и пароль при авторизации. Е...
Евгений
19
Ребят, кто сталкивался с тем, что Electron.js не разворачивает билд React.js-приложения? Голый body в чёрном цвете, как и должно быть, но остального - нет. Билд работает исп...
..
6
Anyone knows how to build this widget in Flutter? I have all the assets for round stations and the road, but how can I make the my widget animate between these stations? And h...
Mohammad Zamani
9
Карта сайта