Home > database >  Spring 5 - Chain reactive webclient calls
Spring 5 - Chain reactive webclient calls

Time:05-03

I'm trying to learn how to use the reactive WebClient in Spring 5. Let's say I have 3 calls I need to make:

  1. Get an access token
  2. Get a list of accounts
  3. For each account, get a list of transactions.

Here, calls 2 and 3 each depend on the output of 1, whilst 3 also depends on the output of 2.

I know I can do something like:

accessTokenService
    .getAccessToken()
    .flatMapMany(accountsService::getAccounts)
    ...

But any subsequent calls to flatMap or doOnNext (or anything else) only have access to the accounts, not the access token.

My question I think boils down to:

If call 2 depends on the output of call 1, and call 3 depends on the output of calls 1 & 2, is there a standard way to accomplish this without having to use block()?

Edit for clarification: Call 3 requires the output of call 1 an input, and also the output of call 2 as input, e.g.:

accessTokenService
    .getAccessToken() // Call 1
    .flatMapMany((accessToken) -> accountsService.getAccounts(accessToken)) // Call 2
    .flatMapMany((accessToken, accounts) -> transactionService.getTransactions(accessToken, accounts)) // Call 3
    ...

CodePudding user response:

Assuming the data classes Account, Token and Transaction, and following service layer structure:

interface AccessTokenService {
    Mono<Object> getAccessToken();
}

interface AccountService {
    Flux<Account> getAccounts();
    Flux<Transaction> getTransactions(Account account);
}

Then you can get all the transaction together for each account after receiving the token with this way:

Flux<Transaction> transactions = accessTokenService.getAccessToken()
                .flatMapMany(token -> accountService.getAccounts())
                .flatMap(account -> accountService.getTransactions(account));

What happens next with the transactions Flux is left to you:

  • You can block the first/last result.
  • You can return them all through the REST controller.
  • You can let them all consume it by a subscriber or R2DBC, you name it.

CodePudding user response:

You could achieve it using:

  1. Reactor Context, since version 3.1.3.
  2. Reactor Tuple.
  3. Create a wrapper object which contains data && access token.
  • Related