
Mykola
22.03.2018
18:11:14
кстате, для изменения иммутабельных сущностей линзы всякие придуманы
https://habrahabr.ru/post/230649/
@fes0r ^ посмотри сам)
чего только функциональщики не придумают, чтоб их функциональщина работала)

Google

Roman
22.03.2018
18:20:33
@fes0r Как кстати лучше конструировать сущность, содерщащую VO? Передавать VO в конструкторе или сделать кучу параметров и внутри конструктора сущности самому собрать VO?

Mykola
22.03.2018
18:23:20
парвый вариант

Roman
22.03.2018
18:28:38
И ещё вопрос - а где лучше делать валидацию данных, которые я получаю извне? Только на уровне получаемых данных? Или внутри доменных сущностей тоже?

Bohdan
22.03.2018
18:29:00
поясни

Roman
22.03.2018
18:33:18
поясни
C#
Предположим есть вот такой класс, описывающий простую сущность
public class User
{
public User(string name) : this()
{
Name = name;
}
private User()
{
Id = 0;
CreationDate = DateTimeOffset.UtcNow;
}
public long Id { get; private set; }
public string Name { get; private set; }
public DateTimeOffset CreationDate { get; private set; }
}
Вот мне надо проверить имя при создании пользователя. Я могу навесить атрибуты на модель данных запроса, используемую для создания пользователя, а могу выполнять эту проверку в самом пользователе. Как лучше?
Типа вот такую модельку сделать для создания пользователя
public class CreateUserViewModel
{
[Required]
[MaxLength(200)]
public string Name { get; set; }
}
И выполнить все проверки разом и вернуть на фронт сразу пачку ошибок валидации


Uiiuviiw
22.03.2018
18:39:47
все зависит от того где с какого слоя модель юзер. но в любом случае, зачем валидатор м
vo засовывать?
кроме того зависит от самой вью, она может быть интерактивной и говорить что все неправильно при каждом символе
но валидировать должна модель создаёщая vo модели юзер
это если чисто архитектурно без привязки к реализации какого-то фраймворка

Google

Hell
22.03.2018
19:07:36

Sergey
22.03.2018
19:12:34
и не понимание что такое абстракция

Maksim
22.03.2018
19:12:41

Sergey
22.03.2018
19:13:05
ну и DI и DIP это разные штуки
для DI интерфейсы не нужны)

Roman
22.03.2018
19:16:42
А вот CreateUserViewModel - это то, что приходит в теле веб-запроса (рассматриваем сценарий разработки WebApi)

Sergey
22.03.2018
19:20:03

Bohdan
22.03.2018
19:20:23
я завис вот на этой строчке и понял, что не помню шарп)
public User(string name) : this()

Roman
22.03.2018
19:20:24

Sergey
22.03.2018
19:20:26
либо эти правила - часть валидации VO либо нет, в любом случае юзер про эти правила ничего не должен знать

Roman
22.03.2018
19:20:46

Bohdan
22.03.2018
19:22:25
ну вот твоя вью-моделька - это по суть объект запроса/dto от фреймворка до домена

Roman
22.03.2018
19:23:02
У нас есть атрибуты валидации, которые через рефлекшон работают. И можно разом провалидировать все входные параметры. И с точки зрения фронта это довольно удобно - сделал запрос и сразу полуил отлуп со списком всех свойств и описанием ошибок - где именно и почему эти данные не прошли проверку на корректность.

Sergey
22.03.2018
19:23:42

Google

Bohdan
22.03.2018
19:23:53
ну это разные проверки
твоя сущность может иметь свои проверки (завязанные на какую-то бизнес логику)

Roman
22.03.2018
19:24:17

Bohdan
22.03.2018
19:24:33
а вот твои запросы/эндпоинты могут иметь свои требования к параметрам

Sergey
22.03.2018
19:25:12
http://gorodinski.com/blog/2012/05/19/validation-in-domain-driven-design-ddd/

Roman
22.03.2018
19:27:11
то, что собирается она не в одном месте, не делает ее не DTO :)
Ну вот с одной стороны Ъ DDD вэй - это внутри домена всё проверять. А с другой стороны - это ж не удобно фронту нифига. Ну вот отправил ты форму с 10 полей, 3 корректны, в 4м косяк - вот где внутри домена оно до этого поля прошло - всё выполнится, а дальше получишь сообщение о том, что мол у тебя вот тут ошибка. Поправил, а у тебя ещё потом выясняется что и в 6 поле ошибка и в 9. Но ты эти ошибки узнаёшь по-одной. И грустишь, проклиная автора системы за такое DDD.
Если на атрибутах сделать - то валидируется вся модель (DTO) сразу. Но вопрос - а надо ли тогда эту логику валидации дублировать в домене?

Bohdan
22.03.2018
19:27:57
@fes0r а вот твоя идея с валидацией запроса до его маппинга - как ложится на DDD? или она на это забивает?)

Sergey
22.03.2018
19:28:17
никак не ложится и даже не касается

Bohdan
22.03.2018
19:30:38
еще у меня крутится мысль о том, что в принципе валидация запроса (заполненность и простые ограничения) не всегда относится к домену

Roman
22.03.2018
19:33:37

Bohdan
22.03.2018
19:35:13
ну вот нет у меня сейчас ответа на этот вопрос) собственно об этом мысль и крутится... но еще никуда не выплыла

Roman
22.03.2018
19:36:32
Ну вот я сижу, пет проект делаю и задаюсь этим вопросом)

Hell
22.03.2018
19:52:09
твоя реакция на тестовый ко

Bohdan
22.03.2018
19:52:56

Hell
22.03.2018
19:55:25

Roman
22.03.2018
19:56:23

Google

Bohdan
22.03.2018
19:56:48
наоборот, в сущность такое и ложится
но вот в слой валидации выносить не хочется

Roman
22.03.2018
19:57:02
А лимит этот в отдельном сервисе живёт

Bohdan
22.03.2018
19:57:38
так да, возможно
хотя пример несколько натянутый

Roman
22.03.2018
19:57:45
Как и юзер
В сервисе, который отвечает за аутентификацию живут юзера, но есть данные, которые к аутентификации не относятся - профиль пользователя. Он тоже в отдельном сервисе. А оформление заказа в третьем. Вполне себе реальный кейс.

Bohdan
22.03.2018
19:59:48
что есть "сервис" у тебя?

Roman
22.03.2018
20:00:47
Полноценный процесс со своими тредами и веб-сервером, перед которым ещё nginx стоит, и под которым отдельная базка лежит.
Они могут вполне себе и на разных машинах находиться, если куб так захочет.

Bohdan
22.03.2018
20:02:46
ну то есть у тебя микросервисы типа (вроде относительно адекватные)
ну юзера + профиль можно на две сущности бить

Alan
22.03.2018
20:03:15
пользователь отдельно а customer = профиль с заказом вместе живут?

Roman
22.03.2018
20:03:25

Bohdan
22.03.2018
20:03:58
просто эта тема местной аудиторией уже в симфони чате обсуждалась

Roman
22.03.2018
20:05:51

Bohdan
22.03.2018
20:06:17
у меня тоже есть подобная беда) сейчас об этом задумался

Roman
22.03.2018
20:06:57
Тогда получается это какой-то сервис, живущий между сущностями и обрабочиками команд, который знает про инфраструктуру (какие сервисы подёргать, чтобы инфу собрать), ну либо не знает и ему инфу дают, но всё же, который живёт за пределами сущности.

Alan
22.03.2018
20:07:06
ну типа домен подтечет в инфраструктуру

Google

Roman
22.03.2018
20:07:29
Есть ещё один прикольный момент. Когда надо часть инфы из профиля, который живёт в другом сервисе, в момент выдачи токена - подгрузить, чтобы часть данных в id_token сложить (роли там всякие, телефоны, ФИО, мыло, чтоб на UI рисовать не дёргая никого). То есть сервис, отвечающий за аутентификацию начинает зависеть от сервиса профилей, доступ к которому осуществляется по токену. То есть OAuth сервис должен запросить токен сам у себя (!!!), чтобы дать его сервису профилей, чтобы тот его провалидировал у сервиса OAuth и выдал профиль по запросу, который этот OAuth сервис и делает))
Вот такой лолкек чебурек микросервисный
И одно без другого не работает
Но с другой стороны есть куча данных - типа тех же ролей, лимитов всяких, которые являются динамичными и рулятся юзерами через API, который этот сервис профилей предоставляет. То есть просто совместить эти 2 сервиса неправильно, так как сервис, отвечающий за аутентификацию реализует только её и больше ничего.


Alan
22.03.2018
20:13:46
ну там где профили это oauth server ? он же и ответит данными клиенту в соответствии со скоупом и запрашиваемыми полями, вместо него наверно можно представить другой oauth сервер
тут oauth изолирует их нет?


Roman
22.03.2018
20:14:06
там даже не oauth, а oidc
где профили это UserProfileApi
А где OpenID Connect - то IdentityServer
"То ли дело в монолите)" - задумываешься в такие моменты
Есть ещё один прикольный момент. Когда надо часть инфы из профиля, который живёт в другом сервисе, в момент выдачи токена - подгрузить, чтобы часть данных в id_token сложить (роли там всякие, телефоны, ФИО, мыло, чтоб на UI рисовать не дёргая никого). То есть сервис, отвечающий за аутентификацию начинает зависеть от сервиса профилей, доступ к которому осуществляется по токену. То есть OAuth сервис должен запросить токен сам у себя (!!!), чтобы дать его сервису профилей, чтобы тот его провалидировал у сервиса OAuth и выдал профиль по запросу, который этот OAuth сервис и делает))
Кстати наверное такое решается вынесением всего менеджмента юзеров в отдельный сервис, в защищённом контуре.

Anton
22.03.2018
22:12:28
Такое случается когда нет понимания что есть пользователь, а что аккаунт

Sergey
22.03.2018
22:12:50
Есть ещё один прикольный момент. Когда надо часть инфы из профиля, который живёт в другом сервисе, в момент выдачи токена - подгрузить, чтобы часть данных в id_token сложить (роли там всякие, телефоны, ФИО, мыло, чтоб на UI рисовать не дёргая никого). То есть сервис, отвечающий за аутентификацию начинает зависеть от сервиса профилей, доступ к которому осуществляется по токену. То есть OAuth сервис должен запросить токен сам у себя (!!!), чтобы дать его сервису профилей, чтобы тот его провалидировал у сервиса OAuth и выдал профиль по запросу, который этот OAuth сервис и делает))
интересный момент что зависят они просто так, потому что ты решил никого не дергать)
ИМХО складывать инфу в токен надо не для того что бы на клиенте эту инфу читать.
клиент сам может на сервак сходить и все узнать.

Anton
22.03.2018
22:13:55

Bohdan
22.03.2018
22:14:27

Roman
22.03.2018
22:14:30

Bohdan
22.03.2018
22:15:18