1
votes

I'm trying to move our registration flow to a reactive setup with Spring Webflux as a POC, we've used AxonFramework to implement CQRS and ES. Our command flow was transformed fairly straight forward, but I'm having trouble transforming our query side.

The problems arrises when I try to transform a point-to-point query that returns a Mono response type, if I specify a Mono ResponseType I get the "No Handler found for [query] with response type"

Can anyone help me figure out how to handle queries with Mono ResponseTypes?

the query handler:

@QueryHandler
fun handleIsEmailUniqueQuery(query: IsEmailUniqueQuery): Mono<Boolean> =
        accountRepository.findAccountByEmail(query.email)
                .flatMap { Mono.just(true) }
                .switchIfEmpty(Mono.just(false))

the code calling the query gateway

fun validateEmailUnique(request: CreateRegistrationRequest): Mono<CreateRegistrationCommand> =
        Mono.fromFuture(queryGateway.query(IsEmailUniqueQuery(request.email), ResponseTypes.instanceOf(Mono::class.java)))
                .flatMap { mono ->  mono.cast(Boolean::class.java)}
                .flatMap { isEmailUnique ->
                    when (isEmailUnique) {
                        true -> Mono.just(CreateRegistrationCommand(request.email, request.password, UUID.randomUUID().toString()))
                        else -> Mono.error(DomainValidationException("ERR_EMAIL_UNIQUE"))
                    }
                }
1

1 Answers

2
votes

So after re-reading the axon documentation I realized that I could return a CompletableFuture instead, after a small refactor it finally worked

QueryHandler:

@QueryHandler
fun handleIsEmailUniqueQuery(query: IsEmailUniqueQuery): CompletableFuture<Boolean> =
        accountRepository.findAccountByEmail(query.email)
                .flatMap { Mono.just(false) }
                .switchIfEmpty(Mono.just(true))
                .toFuture()

code that calls the queryGateway

fun validateEmailUnique(request: CreateRegistrationRequest): Mono<CreateRegistrationCommand> =
        Mono.fromFuture(queryGateway.query(IsEmailUniqueQuery(request.email), ResponseTypes.instanceOf(Boolean::class.java)))
                .flatMap { isEmailUnique ->
                    when (isEmailUnique) {
                        true -> Mono.just(CreateRegistrationCommand(request.email, request.password, UUID.randomUUID().toString()))
                        else -> Mono.error(DomainValidationException("ERR_EMAIL_UNIQUE"))
                    }
                }