Как сделать несколько вызовов Spring Webclient параллельно и дождаться результата? - PullRequest
0 голосов
/ 05 июня 2019

Я новичок в программировании Reactive, и я хотел бы сделать два вызова API параллельно, обработать результаты и вернуть простой массив или список элементов.

У меня есть две функции, одна возвращает Flux идругой возвращает Mono, и я делаю очень простую логику фильтрации для объектов, испускаемых Flux, в зависимости от результата этого Mono.

Я пытался использовать zipWith, но только один элемент дошел до конца, неважнокакая логика фильтрации.Также я пытался с block, но это не разрешено внутри контроллера: /

@GetMapping("/{id}/offers")
fun viewTaskOffers(
        @PathVariable("id") id: String,
        @AuthenticationPrincipal user: UserPrincipal
) : Flux<ViewOfferDTO> {
    data class TaskOfferPair(
        val task: TaskDTO,
        val offer: ViewOfferDTO
    )

    return client.getTaskOffers(id).map {
            it.toViewOfferDTO()
        }.zipWith(client.getTask(id), BiFunction {
            offer: ViewOfferDTO, task: TaskDTO -> TaskOfferPair(task, offer)
        }).filter {
            it.offer.workerUser.id == user.id || it.task.creatorUser == user.id
        }.map {
            it.offer
        }
}
  • getTaskOffers возвращает поток OfferDTO
  • getTask возвращаетMono of TaskDTO

Если вы не можете ответить на мой вопрос, расскажите, по крайней мере, как выполнять несколько вызовов API параллельно и дождаться результатов в WebClient

1 Ответ

1 голос
/ 06 июня 2019

Как вы уже поняли, zipWith вам там не поможет, так как будет выдавать min(a.size, b.size), что всегда будет 1, если один из них будет Mono.

Нотак как эти два независимы, вы можете просто разделить их:

val task: Mono<TaskDTO> = client.getTask(id)
val result: Flux<ViewOfferDTO> = 
task.flatMapMany {t ->
        client.getTaskOffers(id).map {offer ->
            t to offer
        }
    }.filter {
        it.second.workerUser.id == user.id || it.first.creatorUser == user.id
    }.map {
        it.second
}

Обратите внимание, что если вы хотите иметь пару элементов, вы можете использовать встроенный Pair.

Также,эта проверка не имеет большого смысла, так как у вас есть только Mono: it.first.creatorUser

...