Работа с dto для создания API с DDD

Я начинаю работать с dto (объектами передачи данных), и у меня есть некоторые сомнения относительно лучшего способа построения системной архитектуры API.

Представьте себе доменную сущность "A", имеющую отношение к "B", "C" и "D". У нас есть сервис 'S', который возвращает список json со всеми буквами "A". Правильно ли создать "ADTO" в этом сервисе, заполнить "BDTO", "CDTO" и "DDTO"? Если тогда у нас есть другой сервис "S2", и нам нужно вернуть определенный набор "B", то нам нужно создать другое дерево "B2DTO" с "C2DTOS", "D2DTO"...? Это правильный способ сделать это?

Я вижу, что таким образом у нас будет огромное и сложное дерево DTO с конкретными DTO для каждого варианта использования.

РЕДАКТИРОВАТЬ:

Я забыл часть сборщиков. Нужно ли реализовывать разные ассемблеры для каждого DTO? например, для объекта A у нас есть два DTO. Могу ли я использовать один и тот же ассемблер или лучше иметь A1Assembler и A2Assembler?

2 ответа

Я думаю, ты ошибаешься, каковы твои DTO. Грубо говоря, у вас будет 2 вида DTO: 1) они могут быть объектами вашего домена, затем вы можете вернуть ADTO, BDTO и CDTO. Но эти DTO могут быть довольно последовательными (почему B2DTO будет отличаться от BDTO)

Если вы посмотрите на то, что ваш JSON будет смотреть на

{
 Id: 1
 name: "foobar",
 $type: "A",
 B: [ {
      name: "b-bar",
      $type: "B"}]
 CIds: [ 2,23, 42]
}

Здесь вы видите 2 вида объектов, некоторые (B) возвращаются полностью в вашем DTO как подобъекты. Другие (например, C) поворачиваются по Id и могут запрашиваться отдельно. Если это S2, который реализует запрос C или нет, вам все равно.

2) Когда вы попадаете на такую ​​архитектуру, как CQRS, вы получаете разные DTO. (проекции или команды), но тогда вы также увидите это в названии DTO. Например, AListOnOverviewPageDTO, AUserEditDetailDTO и т. Д.

Теперь имеет смысл иметь разные DTO, поскольку они являются проекциями, представляющими очень разные варианты использования. (и не полный объект, как обычно в DDD)

Обновление Причина, по которой вы хотите разные DTO, двояки. Прежде всего, это позволяет оптимизировать каждый звонок отдельно. Возможно, список должен быть быстрее, поэтому (с помощью CQRS) вы можете поместить правильные индексы в свои данные, чтобы ваш listDTO возвращался быстрее. Это позволяет легче рассуждать о случаях использования. Так как каждый DTO представляет 1 сценарий использования / экран (В противном случае вы получите все в порядке в userlistDTO, мне нужно заполнить только эти 3 поля в этом случае... и т. Д.). Кроме того, вы должны убедиться, что ваш API честен. НИКОГДА не возвращайте поле "возраст" с пустыми данными, но какой-либо другой вызов возвращает того же пользователя, но с другим вызовом возвращает того же пользователя с реальным возрастом. Это делает ваш бэкэнд сломанным. Однако, если бы у меня был вызов /users/list и другой вызов /users/1/detail, было бы естественно, если бы вызовы подробностей возвращали больше полей о конкретном пользователе

Ваши DTO должны представлять собой набор данных, которые вы хотите, чтобы ваш клиент имел. Обычно вы никогда не должны "копировать" свои сущности в DTO, потому что у вас могут быть поля, которыми вы не хотите делиться с миром. Предположим, вы автоматически создаете столбец "отслеживания" с идентификатором того, кто ввел эти данные, или говорите, что у вас есть объект Customer с полями пароля. Вы не хотите, чтобы это было частью ваших DTO. Вот почему вы должны быть очень осторожны при использовании AutoMapper и т. Д.

Когда вы разрабатываете DTO, подумайте о том, что именно нужно вашему клиенту с этой конечной точки. Иногда DTO могут выглядеть одинаково, и это нормально. Кроме того, ваши DTO могут быть настолько простыми или сложными, насколько это необходимо. Один сумасшедший пример, скажем, на странице, где вы показываете исполнителя, его песни, голосование за эти песни и некоторые дополнительные данные.

Если ваш сценарий использования оправдывает это, вы вполне можете поместить все это в DTO. DTO все, что они делают, это несут данные.

ДА, ваши услуги должны вернуть DTOS (POCO).

Кроме того, DTO - просто соглашение об именах. Не увлекайтесь суффиксом "dto". "Командой", исходящей от клиента, является DTO, но в этом случае вы бы назвали его, например, AddNewCustomerCommand.

Имеет смысл?

Другие вопросы по тегам