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:
- Get an access token
- Get a list of accounts
- 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: