Repeat request until condition is met in webflux, based on last response's value

Viewed 2444

Using spring boot reactive web's WebClient, I need to call an API that returns an XML response. The response may hold a NextToken - if it is present I want to call the webservice again using the last returned NextToken value until there's no NextToken present on the response.

The current code returns the correct result for the first and second request, but it doesn't concat the returned values and the third and each consequent requests are duplicates of the second.

How can I conditionally repeat a request until the condition I have below in takeUntil is met, while all the orders are concatenated?

client.request(EU, Orders, ListOrdersRequest.forShipped(userData, LocalDateTime.now().minusDays(7), LocalDateTime.now().minusHours(2).minusMinutes(2)), ListOrdersResponse.class)

    .flatMap(e -> {

      if (e.getListOrdersResult().getNextToken() != null) {
        return client.request(EU, Orders, ListOrdersRequest.byNextToken(userData, e.getListOrdersResult().getNextToken()), ListOrdersByNextTokenResponse.class)
            .mergeWith(x -> Flux.just(e));
      }
      return Flux.just(e);
    })

    .delayElements(Duration.ofMinutes(1))
    .repeat()
    .retryBackoff(10, Duration.ofMinutes(2), Duration.ofMinutes(20))
    .takeWhile(r -> r.getListOrdersResult().getNextToken() != null)
    .checkpoint("nextToken fetched", true)
1 Answers

I think you can use the expand operator - something like this:

client.request(EU, Orders, ListOrdersRequest.forShipped(userData, LocalDateTime.now().minusDays(7), LocalDateTime.now().minusHours(2).minusMinutes(2)), ListOrdersResponse.class)
    .expand(e -> {
         if(e.getListOrdersResult().getNextToken() != null) {
             return client.request(EU, Orders, ListOrdersRequest.byNextToken(userData, e.getListOrdersResult().getNextToken()), ListOrdersByNextTokenResponse.class);
         }
         return Flux.empty();
     });
Related