2

我开始使用 dto(数据传输对象),我对构建 API 系统架构的最佳方式有些怀疑。

想象一个域实体“A”,与“B”、“C”和“D”有关系。我们有一个服务“S”,它返回一个包含所有“A”的 json 列表。在该服务中创建“ADTO”是否正确,填写“BDTO's”、“CDTO's”和“DDTO's”?如果我们有另一个服务“S2”,我们需要返回一组特定的“B's”,那么我们需要创建另一个“B2DTO's”树与“C2DTOS's”,“D2DTO's”......?这是正确的方法吗?

我看到这样,我们将拥有一个庞大而复杂的 DTO 树,每个用例都有一个特定的 DTO。

编辑:

我忘记了汇编程序部分。是否需要为每个 DTO 实现不同的汇编程序?例如,对于实体 A,我们有两个 DTO。我可以使用相同的汇编器还是更好地使用 A1Assembler 和 A2Assembler?

4

2 回答 2

1

我认为你弄错了你的 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 是诚实的。永远不要返回带有空数据的“年龄”字段,但让其他一些调用返回相同的用户,但另一个调用返回具有真实年龄的相同用户。它使您的后端看起来很糟糕。

于 2016-12-19T14:37:36.203 回答
1

您的 DTO 应该代表您希望客户拥有的一组数据。通常,您永远不应该将您的实体“复制”到 DTO 中,因为您可能拥有不想与世界共享的字段。假设您正在自动创建一个带有输入该数据的 ID 的“跟踪”列,或者假设您有一个带有密码字段的客户实体。您不希望它成为您的 DTO 的一部分。这就是为什么在使用 AutoMapper 等时必须格外小心的原因。

当您设计 DTO 时,请考虑您的客户具体从该端点需要什么。有时 DTO 可能看起来一样,这没关系。此外,您的 DTO 可以根据需要简单或复杂。一个疯狂的例子,假设你在一个页面上展示了一位艺术家、他的歌曲、这些歌曲的投票率和一些额外的数据。

如果您的用例证明了它的合理性,您很可能将所有这些都放入 DTO。DTO 他们所做的只是携带数据。

是的,您的服务应该返回 DTOS (POCO)。

此外,DTO 只是命名约定。不要被“dto”后缀所困扰。来自客户端的“命令”是 DTO,但在这种情况下,您可以将其称为 AddNewCustomerCommand。

说得通?

于 2016-12-19T16:46:16.240 回答