Spring WebFlux Difference Between Between DTOs

- 1 answer

I use Spring boot reactive web flux for my rest endpoint.

What is the difference between :

public Mono someMethod(@RequestBody SomeDTO someDto){


public Mono someMethod(@RequestBody Mono<SomeDTO> someDTO) {

I don't understand the difference in input argument to my controller method . I know one is pojo and the other in mono but what does it mean from reactive point of view?



First things, some background. You are using the 1.4. Annotated Controllers classes for WebFlux. These implementations are based on the 1.5. Functional Endpoints classes. I would recommend using the Functional Endpoints directly.

From a reactive POV you have to understand that you need to create the reactive flow. In the Mono method this has been created for you, in the SomeDTO method you should probably use Mono.just(someDTO) to create it.

What is important to understand is that statement in the creation will be executed during the build phase not the execution phase of the reactive. The build phase is not executed asynchronously.

So, consider two mono creation statements.

return Mono.just(Thread.sleep(1000));


return Mono.just(1000).map(Thread::sleep);

Yes, I know it won't compile because of interrupted exception, but in the first case the Mono won't be returned to the client until 1 second and then it will do nothing when subscribed to. In the second case the mono will be returned to the client right away and will wait one second after it is subscribed to. The second one is what you are striving for.

What does it mean to you? Consider

return Mono.just(;



In the first case, as above, someDto will be saved in the repo and then the mono will be returned to the client and will do nothing when subscribed to. Wrong! In the second case the mono will be returned to the client, the thread released back to the webflux framework for use in another request, and someDto will be saved when the client subscribes to the returned mono. What you are striving for.

Do it correctly with your first case by doing

return Mono.just(someDto).map(repo::save);

This is effectively doing Mono.just(someDto) yourself whereas in your second case the webflux framework is doing it for you.

Which to choose? If you are just going to wrap someDto in a mono and use it then might as well have the framework do it for you or use the functional endpoints. If you are going to create a mono for some other reason and then use someDto during a mapping process use your first case. This second reason is, IMHO, a rare use case.

Typically when using the functional endpoints you will end up doing request.bodyToMono(Person.class) which is equivalent to your second case and what is done by the framework for you in your second case.