Hello I try to use WebClient (netty) in synchronous style:

return internalWebClient
                .post()
                .uri(composeUri(ACCOUNTS_LIST_URL))
                .syncBody(userCodes)
                .retrieve()
                .bodyToFlux(UserResponse.class)
                .collectList()
                .block();

Documentation - https://github.com/spring-projects/spring-framework/blob/master/src/docs/asciidoc/web/webflux-webclient.adoc - says that it's ok but I got IllegalStateException

java.lang.IllegalStateException: block()/blockFirst()/blockLast() are blocking, which is not supported in thread reactor-http-nio-4
    at reactor.core.publisher.BlockingSingleSubscriber.blockingGet(BlockingSingleSubscriber.java:77)
    at reactor.core.publisher.Mono.block(Mono.java:1494)

Can you explain how to use WebClient in synchronous style / what's wrong / is documentation correct?

Comment From: ilya-murzinov

It means that you are executing this code in a thread which can not be blocked, in your case reactor-http-nio-4. If you run this code in main thread, or any other, it will work.

Comment From: fedotxxl

After a lot of debugging, I realized that I can't block in map method of webClient

webClientInternal.get()
        .uri("https://ya.ru")
        .retrieve()
        .bodyToMono(String.class)
        .map(s -> {
            return webClientInternal.get()
                    .uri("https://ya.ru")
                    .retrieve()
                    .bodyToMono(String.class)
                    .block();
        })
        .block();

I fixed it with:

webClientInternal.get()
        .uri("https://ya.ru")
        .retrieve()
        .bodyToMono(String.class)
        .publishOn(Schedulers.elastic())
//        .publishOn(Schedulers.parallel())
//        .publishOn(Schedulers.single())
        .map(s -> {
            return webClientInternal.get()
                    .uri("https://ya.ru")
                    .retrieve()
                    .bodyToMono(String.class)
                    .block();
        })
        .block();
  ```

It's weird for me but looks like it's ok in reactor

**Comment From: rstoyanchev**

To be more precise, you can't block when making a nested call, which in this case happens to be a `map`, because at that point you're on a Reactor Netty (event loop) thread, processing a response from the server. 

There is no need to block. Use `flatMap` for such nested calls:

```java
webClientInternal.get()
        .uri("https://ya.ru")
        .retrieve()
        .bodyToMono(String.class)
        .flatMap(s ->
            webClientInternal.get()
                    .uri("https://ya.ru")
                    .retrieve()
                    .bodyToMono(String.class)
        )
        .block();

Comment From: sagar11988

The potential issue because of you tried to call blocking the operation with a non-Blocking Netty container. Please add below dependencies

          <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-webflux</artifactId>
    </dependency>

if you want to use WebClient in a blocking form, it seems that you need to operate it in a threaded environment that supports blocking

Code Snippet for reference : blockingCodeSpringFramwork

Comment From: canereren123

org.springframework.boot spring-boot-starter-web org.springframework.boot spring-

Your suggestion is wrong, because you are making the project synhronus and then it will work since it is not using netty http threads anymore. When you configure the application as above then the project is not using webflux anymore instead it uses spring web shich is synhronus. If you remove spring-boot-starter-web you will have the same problem again.

spring-boot-starter-web : Synchronus Http Servlet Request spring-boot-starter-webflux : Asynchronus Http Netty Request

Comment From: rstoyanchev

The snippets shown are not related to running on WebFlux and would work that way even in a simple client app without a server main method. It's that there are two remote calls, one nested within the other, so the nested one ends up being executed on a Reactor Netty thread.

Note however that in this case, with multiple remote calls involving a reactive client, there is no need to block within the Reactor chain, and no need to switch threads via publishOn. You can declare the call sequence without blocking, and then block only at the end. So, remove the block() for the nested call and flatMap instead of map:

webClientInternal.get()
        .uri("https://ya.ru")
        .retrieve()
        .bodyToMono(String.class)
        .flatMap(s -> {
            return webClientInternal.get()
                    .uri("https://ya.ru")
                    .retrieve()
                    .bodyToMono(String.class);
        })
        .block();

Comment From: morohon

@rstoyanchev I apologize for bringing up an old issue. But I ran into a similar problem when using the interceptor. The problem was described here: https://stackoverflow.com/questions/77360338/spring-webclient-interceptor-in-synchronous-mode

Do I understand correctly that, judging by the issues, it is not possible to use the interceptor in blocking mode? Maybe there are some ways out?

Comment From: bclozel

@morohon I've replied to your SO question. The same advice applies there, the flatMap operator helps to compose ansynchronous operations.