我有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相互通信。
我有models module
所有DTO课程。每个MS都包含models module
在maven。
1 MS发送carDto 2 MS接收CarDto并转换为域。为此我可以使用几种变体:
mapstruct
:@Mapper public interface CarMapper { CarMapper INSTANCE = Mappers.getMapper(CarMapper.class ); CarDto carToCarDto(CarDomain car); }
并使用:
CarDto carDto = CarMapper.INSTANCE.carToCarDto(carDomain);
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
private String name;
到
private String name1;
当我们构建项目时,我们会在这一行上收到错误:
carDto.setName(car.getName());// getName not found becose now getName1
但这种方式很难。对于每个dto / domain模型,我们需要创建映射器并编写每个字段。在1个变体中它更容易但如果改变我们在运行时会得到错误。
告诉我如何匹配/映射模型dto / domain的最佳方法?
答案 0 :(得分:4)
当我们构建微服务时,在模型模块中,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类的模型模块。
这可能是一个错误;很难说。拥有一个通常以不向后兼容的方式发展的共同核心肯定是错误的。这种习惯应该改变。
答案 1 :(得分:0)
考虑使用Java bean映射器。看到 any tool for java object to object mapping?
此类映射器非常灵活,可以在不需要样板代码的情况下弥合模型之间的细微差别。