【问题标题】:Best way to mapping dto/domain for transport between microservices映射 dto/domain 以在微服务之间传输的最佳方式
【发布时间】:2017-12-13 06:11:27
【问题描述】:

我有 DTO 和 DOMAIN 模型:

@Data
public class CarDomain {
    private String name;
    private int year;
    private String color;
}

和

@Data
public class CarDto {
    private String name;
    private int year;
    private String color;
}

我有 3 个微服务 (MS) 通过 RabbitMq 相互通信。 我有所有 DTO 课程的models module。每个MS包括models module 在 Maven 中。

1 MS 发送 carDto 2 MS 接收 CarDto 并转换为域。为此,我可以使用几种变体:

  1. 使用库例如mapstruct:
@Mapper
public interface CarMapper {
    CarMapper INSTANCE = Mappers.getMapper(CarMapper.class );
    CarDto carToCarDto(CarDomain car);
}

并使用:

CarDto carDto = CarMapper.INSTANCE.carToCarDto(carDomain);
  1. 创建手动映射器:
class CarMapper {
        public static CarDto toDto(CarDomain car) {
            CarDto carDto = new CarDto();
            carDto.setName(car.getName());
            carDto.setYear(car.getYear());
            carDto.setColor(car.getColor());
        }
    }

现在我们使用 2 个变体。因为当我们构建微服务和models module 某些 DTO 模型更改字段时,我们会在编译时出错。例如,有人在models module 中更改此 dto 模型的名称

private String name; 

到

private String name1;

当我们构建项目时,我们在这一行得到错误:

carDto.setName(car.getName());// getName not found becose now getName1

但这很难。对于每个 dto/domain 模型,我们需要创建映射器并编写每个字段。在 1 个变体中它更容易,但如果 dto 更改我们会在运行时出错。

告诉我如何匹配/映射模型 dto/domain 的最佳方法?

【问题讨论】:

标签: java domain-driven-design microservices dto


【解决方案1】:

因为当我们构建微服务和模型模块中的某些 DTO 模型更改字段时,我们会在编译时出错。

您面临的问题通常被认为是消息版本控制。

微服务的一个关键思想是它们可以相互独立地重新部署;您应该能够随时更改它们而不会破坏其他所有内容。为了实现这一点,我们将微服务之间的耦合限制为它们共有的消息。

因此;因此,非常重要让消息模式“正确”。

正确在这种情况下,并不意味着您在第一时间就确定了要发送的正确消息,而是您在了解消息如何变化以及消息结构支持哪些方面投入了前期设计资金这些变化。

我所知道的关于该主题的最佳单一参考书是 Greg Young 的书 Versioning in an Event Sourced System。

Greg 提出了使用“弱模式”来支持向前和向后兼容性的案例;基本思路是

  • 字段的含义永远不会改变
  • 消费者必须忽略并且必须转发它不理解的字段
  • 大多数(全部?)字段应该是可选的;消费者必须为消息中缺少某些数据元素的事件做好准备。这可能意味着准备一个可接受的默认值,或替代处理。

牢记基础;您可以查看Avro、Thrift、Protocol Buffers 的详细信息,以了解标准化格式的发展趋势。 Martin Kleppmann 对Schema Evolution in Avro, Protocol Buffers, and Thrift 的讨论可能是一个很好的中间步骤。

消息规则非常重要——模式是微服务 API 的一部分。对 API 进行向后不兼容的更改会带来很大的风险,不应掉以轻心。

我有包含所有 DTO 类的模型模块。

这可能是一个错误;很难说。拥有一个经常以不向后兼容的方式发展的公共核心肯定是一个错误。这种习惯应该改变。

【讨论】:

    【解决方案2】:

    考虑使用 Java bean 映射器。看 any tool for java object to object mapping?

    此类映射器非常灵活,可以在模型之间弥合细微差异,而无需样板代码。

    【讨论】:

      猜你喜欢
      • 2020-01-15
      • 2020-07-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-11-26
      • 2018-09-19
      • 2021-07-24
      相关资源
      最近更新 更多