Search code examples
javaspringreactive-programmingspring-webfluxspring-webclient

Spring reactive webClient - how to call methods on a Mono


New to reactive programming and trying to create a reactive service via WebFlux and WebClient.

The flow of the method is like

  1. POST request and wait for response back
  2. Body of response to a mapping service (which has some other business logic) and which returns a Recommendations type
  3. Create a ResponseEntity
  4. Create a Mono of type Mono<ResponseEntity>

Question is this a valid of way doing this as in should I be using .exchange()? and is there a way of chaining these methods instead of individual methods

current implementation:

private Mono<ResponseEntity<Recommendations>> myMethod(final Request request, final String variantName) {

    Mono<String> response = webClient.build()
            .post()
            .uri(uri)
            .header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
            .header(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON_VALUE)
            .bodyValue(requestBody)
            .retrieve().bodyToMono(String.class);

    var recommendations = ((XYZResponseMapper) responseMapper).mapReactive(request, response, useCaseId, variantName); //return type Recommendations
    var entity = new ResponseEntity<>(recommendations, nullHeaders, HttpStatus.OK);
    return Mono.just(entity);

}

Solution

  • After a lot of reading and experimenting I managed to make it work with the following:

        return webClient.build()
                .post()
                .uri(uri)
                .header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
                .header(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON_VALUE)
                .bodyValue(requestBody)
                .retrieve()
                .toEntity(String.class)
                .publishOn(Schedulers.boundedElastic())
                .map(x -> {
               
                    var recs = processResponse(request, x.getBody(), useCaseId, variantName);
                    return new ResponseEntity<GatewayRecommendations>(recs, x.getStatusCode());
                });