0

I'm building a plain old Java desktop application with Swing, but needs to make Rest calls to a backend. Since we're in a modern async world, and the tools exists, i want to make async calls to the backend, display a progressbar, and hide it when the calls are done.

Using Spring WebClient seems the way to go, and it works well, until i need to chain multiple async Rest calls. In that case, the second call never respond... I see the backend really receives the 2 calls, but the client side never resumes.

public void notWorking(CurrentTool toolDto, Consumer<ToolDto> successCallback) {
    webClient.post()
            .uri(uriBuilder -> {
                return uriBuilder
                        .path("/tools/{id}")
                        .build(toolDto.getTool().getToolId());
            })
            .body(BodyInserters.fromObject(toolDto.getTool()))
            .retrieve()
            .bodyToMono(Long.class)
            .subscribe(id -> {
                webClient.get()
                        .uri(uriBuilder -> {
                            return uriBuilder
                                    .path("/tools/{id}")
                                    .build(id);
                        })
                        .retrieve()
                        .bodyToMono(ToolDto.class)
                        .subscribe((response) -> {
                            successCallback.accept(response);
                        });
            });
}

However, if I make the same calls but in a blocking way, everything works fine. (Except it's sync, so my loading bar won't work...)

public void working(CurrentTool toolDto, Consumer<ToolDto> successCallback) {
    Long id = webClient.post()
            .uri(uriBuilder -> {
                return uriBuilder
                        .path("/tools/{id}")
                        .build(toolDto.getTool().getToolId());
            })
            .body(BodyInserters.fromObject(toolDto.getTool()))
            .retrieve()
            .bodyToMono(Long.class)
            .block();

    webClient.get()
            .uri(uriBuilder -> {
                return uriBuilder
                        .path("/tools/{id}")
                        .build(id);
            })
            .retrieve()
            .bodyToMono(ToolDto.class)
            .subscribe((response) -> {
                successCallback.accept(response);
            });
}
JSlain
  • 566
  • 3
  • 20

1 Answers1

0

You should try to avoid nesting subscribes. You can use flatmap instead.

public void shouldBeWorking(CurrentTool toolDto, Consumer<ToolDto> successCallback) {
    webClient.post()
            .uri(uriBuilder -> uriBuilder
                    .path("/tools/{id}")
                    .build(toolDto.getTool().getToolId()))
            .body(BodyInserters.fromObject(toolDto.getTool()))
            .retrieve()
            .bodyToMono(Long.class)
            .flatmap(id -> webClient.get()
                    .uri(uriBuilder -> uriBuilder
                            .path("/tools/{id}")
                            .build(id))
                    .retrieve()
                    .bodyToMono(ToolDto.class))
            .subscribe(successCallback::accept);
}
123
  • 10,778
  • 2
  • 22
  • 45