I'm currently building a reactive app using kotlin quarkus and mutiny, being new to reactive programming i wonder what's the best way to handle the following workflow :
Here's my code for now :
fun createCard(creationOrder: CreationOrder): Uni<CardCreationResult> {
return creationOrdersRepository.findByOrderId(creationOrder.orderId)
.onItem().transform {item ->
if (item != null) {
CardCreationResult.AlreadyCreated
} else {
creationOrdersRepository.save(creationOrder)
//TODO external webservice call
val cardNumber = UUID.randomUUID().toString()
creationOrdersRepository.updateCardNumberAndStatus(externalServiceCallResult)
CardCreationResult.Created
}
}
}
This method will eventually be called by a rest endpoint.
creationOrdersRepository.save
and creationOrdersRepository.updateCardNumberAndStatus
returns a CompletableFuture (i'm using the quarkus amazon dynamodb client).
Is this the right way to do it ? Should i wrap the save and updateCardNumberAndStatus results in Uni (i have been trying to but keep getting type error) ?
I don't believe your code does what you expect. If I understand correctly you need to "save" and "update" before emitting your result. So, you need something like (in Java, as my Kotlin is not great):
return creationOrdersRepository.findByOrderId(creationOrder.orderId)
// We will be returning a Uni as the save, update and the web service are
// async
.onItem().transformToUni(item -> {
if (item != null) {
return Uni.createFrom().item(CardCreationResult.AlreadyCreated);
} else {
// Create an Uni from the save operation
Uni<Void> save = Uni.createFrom().completionStage(() ->
creationOrdersRepository.save(creationOrder));
// This uni represents the invocation of the remote service
Uni<String> webService = callWebService();
// we chain the operations save -> web service -> update -> Created
return save
.chain(webService)
.chain(externalServiceCallResult ->
Uni.createFrom().completionStage(() -> creationOrdersRepository
.updateCardNumberAndStatus(externalServiceCallResult)
)
.replaceWith(CardCreationResult.Created);
}