I have a public API with two endpoints. I have to get an Array of objects as Flux from the first GET endpoint THEN BY calling the second(internal call) GET endpoint Mono(Mono contains List of Objects ) where I have to find an internal Object by id THEN using the found object(List) filter first Flux(each contains List)
I tried in this way but it became a forever stream
public class Test {
String baseUrl = "http://some-site.com/";
private final WebClient webClient = WebClient.create(baseUrl);
@SneakyThrows
public Flux<One> getObjOneFlux(String id) {
Flux<One> oneFlux = loadObjOnes();
Mono<Two> twoMono = loadObjTwo();
return oneFlux.filterWhen(one -> twoMono.map(two -> one.getOneInternalList()
.stream()
.map(One.OneInternal::getName).toList()
.containsAll(
two.getTwoInternalList().stream()
.filter(s -> s.getId().equals(id))
.findFirst().get().getOptions()
)
)
);
}
public Flux<One> loadObjOnes() {
return webClient.get()
.uri(uriBuilder -> uriBuilder.path("/ObjOne").build())
.exchange()
.flatMap(res -> res.bodyToMono(ObjOneResponse.class))
.flatMapIterable(res -> res)
.map(t ->
One.builder()
.id(t.getId())
.mark(t.getMark())
.oneInternalList(t.getOneInternalList())
.build());
}
public Mono<Two> loadObjTwo() {
return webClient.get()
.uri(uriBuilder -> uriBuilder.path("/ObjTwo").build())
.exchange()
.flatMap(res -> res.bodyToMono(Two.class))
.map(s -> Two.builder()
.twoInternalList(s.getTwoInternalList())
.build()).delayElement(Duration.ofSeconds(3));
}
}
@Data
@Builder
class One {
private String id;
private String mark;
private List<OneInternal> oneInternalList;
@Data
@Builder
public static final class OneInternal {
private String name;
}
}
@Data
@Builder
class Two {
private List<TwoInternal> twoInternalList;
@Data
@Builder
public static final class TwoInternal {
private List<String> options;
private String id;
}
}
class ObjOneResponse extends ArrayList<One> {
}