I have a controller which is asking a service to reach a service endpoint to get a list of account numbers, then reach out to another service for each account number and retrieve additional data about that account. The 'happy path' essentially looks like this:
CONTROLLER
@ApiOperation(value = "getRelatedAccounts")
@GetMapping(value = "/relatedaccounts")
public ResponseEntity<RelatedAccounts> getRelatedAccounts(@RequestParam String accountNumber) {
return new ResponseEntity<>(myService.getRelatedAccounts(accountNumber), HttpStatus.OK);
}
SERVICE
public RelatedAccounts getRelatedAccounts(String accountNumber) {
// blah blah, hit the endpoint and get my response of a list of account numbers in relatedAccountsList
Flux<AccountInformation> accountInfoFlux = Flux.fromIterable(relatedAccountsList)
.parallel()
.runOn(Schedulers.elastic())
.flatMap(this::getAccountInformation)
.ordered(Comparator.comparing(RelatedAccounts::getCorrectOrder)) // blah blah, convert from ParallelFlux to Flux
}
OTHER SERVICE
public Mono<AccountInformation> getAccountInformation(String accountNumber) {
WebClient webClient = WebClient.builder()
.baseUrl("http://myurl.com")
.build();
return webClient
.get()
.uri(uriBuilder -> uriBuilder
.queryParam("accountNumber", accountNumber)
.build()
).retrieve()
.bodyToMono(AccountInformation.class) // This doesn't work for us, we get a very complex object as a response and need to parse a few fields.
}
I've spent all day on Google and I don't see anyone else parsing the response they get back, they just magically map it directly onto a perfectly created class. We don't have that option, we need to pluck the accountName from the response body and put it in the AccountInformation object. Does anyone have any idea how to do this?
We ended up doing it a pretty ugly, but extensible and effective way. In our OTHER SERVICE:
public Mono<AccountInformation> getAccountInformation(String accountNumber) {
WebClient webClient = WebClient.builder()
.baseUrl("http://myurl.com")
.build();
return webClient
.get()
.uri(uriBuilder -> uriBuilder
.queryParam("accountNumber", accountNumber)
.build()
).retrieve()
.bodyToMono(String.class) // just get the response as a JSON string
.map(jsonString -> {
ObjectMapper mapper = new ObjectMapper();
JsonNode root = mapper.readTree(jsonString);
// parse/ map out all your information here
return myCustomMappedObject;
})
}