带Spring的DDD Java-存储库返回Mono/Flux

带Spring的DDD Java-存储库返回Mono/Flux,java,spring,mongodb,domain-driven-design,project-reactor,Java,Spring,Mongodb,Domain Driven Design,Project Reactor,我想知道在我使用Java和Spring Boot实现的DDD项目中实现反应式Mongo存储库时遇到的一个问题。假设我们有这样的包结构: /app | |------/application | | | |------/order | | | |------OrderApplicationService.java | |------/domain | |

我想知道在我使用Java和Spring Boot实现的DDD项目中实现反应式Mongo存储库时遇到的一个问题。假设我们有这样的包结构:

/app 
  |
  |------/application
  |        | 
  |        |------/order
  |                 |
  |                 |------OrderApplicationService.java
  |
  |------/domain
  |        |
  |        |------/order
  |                 |
  |                 |------Order.java
  |                 |------OrderRepository.java 
  |
  |------/infrastructure
           |
           |------/mongo
                    |
                    |------MongoOrderRepository.java
I my OrderRepository.java我想要一个保存订单的方法:

public interface OrderRepository {

    Order save(Order order);
}
并在我的应用程序服务中使用它:

@Service
public class OrderApplicationService {

    private final OrderRepository orderRepository;

    public OrderApplicationService(OrderRepository orderRepository) {
        this.orderRepository = orderRepository;
    }

    public void createOrder() {
        //Dumb order creation
        Order createdOrder = clientRepository.save(new Order());
    }
}
接下来,我想编写MongoOrderRepository,它实现了OrderRepository。假设我将使用ReactiveMongoTemplate。问题是它的所有方法都返回Flux或Mono,所以我无法从OrderRepository接口实现我的方法

我认为可能的解决办法是:

  • 使OrderRepository中的“save”方法返回由包装的订单 莫诺。这种方法将使用Reactor来污染域层 特定类型,并打破了域层应为 框架代码免费
  • 开发某种包装层,但这会产生一些 样板代码
  • 将OrderService.java移到基础架构层,但这也打破了一些基本的DDD概念

  • 有人看到了更好的解决方案吗?

    存储库应该对框架代码不可知,这是事实,这是一个很好的实践,但您也需要务实,我有一个存储库,我在其中使用了java lambda,这是一个语言级别的框架

    使用Flux或Mono的好处是什么?作为界面的一部分宣传它们的好处是什么?如果没有,则可以将实现细节保留在存储库实现中,并使接口没有反应对象

    但是,如果这需要跨越应用程序层到端口适配器,那么我看不出将它们放在存储库的接口定义中有任何问题

    也就是说,您可能希望检查另一种方法,使用CQR和六边形体系结构,您可以实现两个方面的最佳效果:

    • 为命令(更新和创建零件)提供干净的存储库界面
    • 使用查询服务(如果您使用java,则为普通POJO,在应用程序包中定义),为查询返回Mono或Flux(阅读部分)

      OrderApplicationService.java(这里是通过命令创建更新删除) OrderQueryService.java(这里是阅读部分)

    您的应用程序服务包含对OrderRepository的引用,查询服务不使用存储库,因为它更直接地查询数据库,例如通过ReactiveMongoTemplate


    例如,在我的查询服务中,我在存储库实现中使用Hibernate时使用了普通JDBC模板。

    更好的标准解决方案是使用Spring数据,而不是编写存储库实现。为什么要使用ReactiveMongoTemplate?你可以选择MongoTemplate。问题是,如果您选择ReactiveMongoTemplate,那么完整的项目代码应该以反应式的方式编写,否则就没有使用它的意义。是的,在这个项目中,我最终将使用MongoTemplate。我只是想知道反应式回购如何与经典的DDD概念相结合,并收集一些关于这方面的观点。谢谢您的回复。不确定,但如果整个堆栈没有反应。。。你没有反应系统