So suppose I want to create e-commerce system. there will be OrderProductCommand which has productId and couponCode. I need to somehow retrieve additional data from query model (price and discount). At first, I tried to use queryGateway like this.
@Aggregate
class UserAggregate {
var balance = BigDecimal.ZERO
@CommandHandler
fun handle(cmd: OrderProductCommand, queryGateway: QueryGateway){
val product = queryGateway.query(FindProductById(cmd.productId), ResponseTypeOf(Coupon::class.java)).get()
val discount = queryGateway.query(FindCouponByCode(cmd.couponCode), ResponseTypeOf(Coupon::class.java)).get()
if (product.price*(1-discount) >= balance){
throw IllegalArgumentException("Insufficient balance")
}
AggregateLifecycle.apply(...)
}
}
but then I read this post is running a query… and I know that this implementation is not good practice I should use Saga which axon already provided instead. So I try to find an example of how to do it properly on this example AxonTrader,but there’s no usage of query gateway. So I don’t know what’s the proper way of doing it could anyone give me an example. one more question, I wonder if I don’t want to use Saga can I handle it inside of a controller like this instead.
@Controller
class UserController {
@Autowired
private lateinit var queryGateway: QueryGateway
@Autowired
private lateinit var commandGateway: CommandGateway
data class OrderProductDTO(
val orderId: String,
val productId: String,
// this provide by admin
val couponCode: String
)
data class OrderProductCommand(
val orderId: String,
val price: BigDecimal,
// this provide by admin
val discount: Int
)
@PostMapping
fun purchaseProduct(dto: OrderProductDTO): CompletableFuture<String> {
val monoProduct = Mono.fromFuture(queryGateway.query(FindProductById(cmd.productId), ResponseTypeOf(Coupon::class.java)))
val monoCoupon = Mono.fromFuture(queryGateway.query(FindProductById(cmd.productId), ResponseTypeOf(Coupon::class.java)))
return Mono.zip(monoProduct, monoCoupon)
.flatMap { (price, discount) -> OrderProductCommand(orderId = dto.orderId, price = price, discount = discount) }
.toFuture()
}
}
or it’s also not a good practice I should always rely on Saga.