<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Project Reactor Archives - Codersee blog- Kotlin on the backend</title>
	<atom:link href="https://blog.codersee.com/tag/project-reactor/feed/" rel="self" type="application/rss+xml" />
	<link></link>
	<description>Kotlin &#38; Backend Tutorials - Learn Through Practice.</description>
	<lastBuildDate>Wed, 16 Apr 2025 04:50:29 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	

<image>
	<url>https://blog.codersee.com/wp-content/uploads/2025/04/cropped-codersee_logo_circle_2-32x32.png</url>
	<title>Project Reactor Archives - Codersee blog- Kotlin on the backend</title>
	<link></link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>While Loop In Project Reactor? Expand as a Solution.</title>
		<link>https://blog.codersee.com/project-reactor-expand/</link>
					<comments>https://blog.codersee.com/project-reactor-expand/#respond</comments>
		
		<dc:creator><![CDATA[Piotr]]></dc:creator>
		<pubDate>Tue, 16 Aug 2022 06:32:34 +0000</pubDate>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Project Reactor]]></category>
		<guid isPermaLink="false">https://codersee.com/?p=3003065</guid>

					<description><![CDATA[<p>In this article, I will show you how to implement an equivalent of a while loop in Project Reactor using the expand() method. </p>
<p>The post <a href="https://blog.codersee.com/project-reactor-expand/">While Loop In Project Reactor? Expand as a Solution.</a> appeared first on <a href="https://blog.codersee.com">Codersee blog- Kotlin on the backend</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<h2 class="wp-block-heading" id="h-1-introduction">1. Introduction</h2>



<p>If you&#8217;ve ever been working with <strong>Project Reactor</strong> and have a need to implement an equivalent of a <strong>while (or do-while) loop</strong>, then you&#8217;ve come to the right place 🙂</p>



<p>In this article, I will show you what exactly the <strong>expand()</strong> method does in Project Reactor and how it can help you to solve the problem of a while (or rather do-while) loop.</p>



<h2 class="wp-block-heading" id="h-2-project-reactor-expand-in-theory">2. Project Reactor Expand in Theory</h2>



<p>As the first step, let&#8217;s try to understand what exactly the <strong>Mono.expand()</strong> method do? According <a href="https://projectreactor.io/docs/core/release/api/reactor/core/publisher/Mono.html#expand-java.util.function.Function-" target="_blank" rel="noopener">to the documentation</a>:</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p>Recursively expand elements into a graph and emit all the resulting element using a breadth-first traversal strategy.</p>
</blockquote>



<p>I know, it might sound a bit confusing, but let&#8217;s look at the following dependency graph:</p>



<figure class="wp-block-image aligncenter"><img fetchpriority="high" decoding="async" width="1024" height="576" src="http://blog.codersee.com/wp-content/uploads/2022/07/reactor_expand_graph-1024x576.png" alt="The image shows a graph used to better ilustrate Mono.defer() method definition." class="wp-image-3003068" srcset="https://blog.codersee.com/wp-content/uploads/2022/07/reactor_expand_graph-1024x576.png 1024w, https://blog.codersee.com/wp-content/uploads/2022/07/reactor_expand_graph-300x169.png 300w, https://blog.codersee.com/wp-content/uploads/2022/07/reactor_expand_graph-768x432.png 768w, https://blog.codersee.com/wp-content/uploads/2022/07/reactor_expand_graph-1536x864.png 1536w, https://blog.codersee.com/wp-content/uploads/2022/07/reactor_expand_graph.png 1920w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<p>As we can see, it presents a hierarchical structure of the parent-child relationships. If we would expand a <code class="EnlighterJSRAW" data-enlighter-language="kotlin">Mono.just(A)</code>, then the values would be emitted in the following order: <strong>A, B, C, D, E, F, G, H</strong>.</p>



<p>This behavior can be used to implement a counterpart of a while loop in Project Reactor.</p>



<h2 class="wp-block-heading" id="h-3-set-up-example-spring-webflux-project">3. Set Up Example Spring WebFlux Project</h2>



<p>With that being done, let&#8217;s implement a simple Spring WebFlux project, which will help us to understand everything even better.</p>



<p>We will expose a simple REST endpoint with pagination and use the <strong>expand()</strong> method to fetch all the results.</p>


<p>[elementor-template id=&#8221;9007393&#8243;]</p>



<h3 class="wp-block-heading" id="h-3-1-imports">3.1. Imports</h3>



<p>As the first step, let&#8217;s add the necessary import to the project:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="raw" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">dependencies {
  implementation("org.springframework.boot:spring-boot-starter-webflux")
}</pre>



<h3 class="wp-block-heading" id="h-3-2-expose-the-test-endpoint">3.2. Expose The Test Endpoint</h3>



<p>Nextly, let&#8217;s expose the example endpoint:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="kotlin" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">@RestController
@RequestMapping("/api")
class ExampleController(
  private val service: ExampleService
) {

  data class ExampleDto(val name: String, val nextPageToken: String?)

  val exampleList = mapOf(
    "" to ExampleDto("Name-1", "token-2"),
    "token-2" to ExampleDto("Name-2", "token-3"),
    "token-3" to ExampleDto("Name-3", "token-4"),
    "token-4" to ExampleDto("Name-4", "token-5"),
    "token-5" to ExampleDto("Name-5", null)
  )

  @GetMapping("/example")
  fun getExample(@RequestParam("token") pageToken: String?): Mono&lt;ExampleDto> =
    pageToken?.let { token ->
      Mono.just(exampleList[token]!!)
    } ?: Mono.empty()

}</pre>



<p>As we can see, the logic is pretty straightforward.</p>



<p>When the API consumer performs a <strong>GET</strong> request with an empty String, the endpoint returns the <code class="EnlighterJSRAW" data-enlighter-language="generic">name</code> and <code class="EnlighterJSRAW" data-enlighter-language="generic">nextPageToken</code> properties:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="json" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">{
    "name": "Name-1",
    "nextPageToken": "token-2"
}
</pre>



<p>The <code class="EnlighterJSRAW" data-enlighter-language="generic">nextPageToken</code> property can be then used to iterate through the entries in the Map. Finally, when the user gets the last record, the <code class="EnlighterJSRAW" data-enlighter-language="generic">nextPageToken</code> property is null and the following request results in the empty Mono being returned.</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p>as a note, I can add that the Google Calendar API works in a similar manner 🙂</p>
</blockquote>



<h2 class="wp-block-heading" id="h-4-project-reactor-while-loop">4. Project Reactor While Loop</h2>



<p>So at this point, we already have our REST endpoint and it&#8217;s time to consume it with a do-while loop in some way.</p>



<h3 class="wp-block-heading" id="h-4-1-add-webclient-config">4.1. Add WebClient Config</h3>



<p>As the first step, let&#8217;s add the WebClient config:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="kotlin" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">@Configuration
class Configuration {

  @Bean
  fun webClient(): WebClient =
    WebClient.builder()
      .baseUrl("http://localhost:8080")
      .build()

}
</pre>



<h3 class="wp-block-heading" id="h-4-2-create-example-service">4.2. Create Example Service</h3>



<p>Nextly let&#8217;s implement the <code class="EnlighterJSRAW" data-enlighter-language="generic">ExampleService</code> and a <code class="EnlighterJSRAW" data-enlighter-language="generic">performRequest</code> function:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="kotlin" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">@Service
class ExampleService(
    private val webClient: WebClient
) {
  
  private fun performRequest(token: String?): Mono&lt;ExampleController.ExampleDto> =
    webClient
      .get()
      .uri { builder ->
        builder
          .path("/api/example")
          .queryParamIfPresent("token", Optional.ofNullable(token))
          .build()
      }
      .retrieve()
      .bodyToMono(ExampleController.ExampleDto::class.java)
}
</pre>



<p>As can be seen, this function is responsible for performing a <strong>GET</strong> request to the <code class="EnlighterJSRAW" data-enlighter-language="raw">http://localhost:8080/api/example</code> endpoint. The <code class="EnlighterJSRAW" data-enlighter-language="raw">token</code> query parameter is set based on the passed argument (which can be null, as well).</p>



<h3 class="wp-block-heading" id="h-4-3-make-use-of-mono-expand-method">4.3. Make Use Of Mono.expand() Method</h3>



<p>Finally, let&#8217;s make use of the Project Reactor <strong>Mono.expand()</strong> method to iterate through the results in a <strong>do-while</strong> style:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="kotlin" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">operator fun invoke() {
  performRequest("")
    .expand { response ->
      performRequest(token = response.nextPageToken)
    }
    .subscribe(System.out::println)
}
</pre>



<p>Now, when we invoke the above function, the following values will be printed to the output:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="raw" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">ExampleDto(name=Name-1, nextPageToken=token-2)
ExampleDto(name=Name-2, nextPageToken=token-3)
ExampleDto(name=Name-3, nextPageToken=token-4)
ExampleDto(name=Name-4, nextPageToken=token-5)
ExampleDto(name=Name-5, nextPageToken=null)
</pre>



<p>As we can see, the initial Mono has been expanded and the <strong>values are published until the endpoint returns the empty Mono.</strong></p>



<h2 class="wp-block-heading" id="h-5-summary">5. Summary</h2>



<p>And that would be all for this article on <strong>how to implement a while (do-while) loop in Project Reactor</strong>.</p>



<p>As always, you can find the source code right here, in <a href="https://github.com/codersee-blog/spring-webflux-expand" target="_blank" rel="noopener">this GitHub repository</a>, and the other articles related to Project Reactor <a href="https://blog.codersee.com/tag/project-reactor/" target="_blank" rel="noopener">here</a>.</p>



<p>If you would like to add anything, or just simply share your thoughts, then please let me know in the comment section. Have a great week and see you in the next articles 🙂</p>
<p>The post <a href="https://blog.codersee.com/project-reactor-expand/">While Loop In Project Reactor? Expand as a Solution.</a> appeared first on <a href="https://blog.codersee.com">Codersee blog- Kotlin on the backend</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.codersee.com/project-reactor-expand/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Mono.just() vs defer() vs fromSupplier() vs create() &#8211; Part 2</title>
		<link>https://blog.codersee.com/mono-just-defer-fromsupplier-create-part-2/</link>
					<comments>https://blog.codersee.com/mono-just-defer-fromsupplier-create-part-2/#respond</comments>
		
		<dc:creator><![CDATA[Piotr]]></dc:creator>
		<pubDate>Tue, 21 Dec 2021 07:30:49 +0000</pubDate>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Project Reactor]]></category>
		<category><![CDATA[Spring WebFlux]]></category>
		<guid isPermaLink="false">https://codersee.com/?p=1809</guid>

					<description><![CDATA[<p>This time, we will focus on differences between just(), defer(), fromSupplier() and create() methods in exceptions and null handling.</p>
<p>The post <a href="https://blog.codersee.com/mono-just-defer-fromsupplier-create-part-2/">Mono.just() vs defer() vs fromSupplier() vs create() &#8211; Part 2</a> appeared first on <a href="https://blog.codersee.com">Codersee blog- Kotlin on the backend</a>.</p>
]]></description>
										<content:encoded><![CDATA[<h2 class="article-heading-introduction">1. Introduction</h2>
<p>In the <a href="https://blog.codersee.com/mono-just-defer-fromsupplier-create-part-1/">previous article,</a> we&#8217;ve covered the basic differences between <strong>Mono.just()</strong>, <strong>defer()</strong>, <strong>fromSupplier()</strong> and <strong>create()</strong> methods. If you haven&#8217;t seen it yet, I highly recommend you to take a while and check it out.</p>
<p>Although we&#8217;ve spent quite some time trying to understand the behavior and possible use cases for each method, it&#8217;s worth to mention that we focused on successful cases. Unfortunately, this is not always the case in real-life scenarios. Provided that, in this article we will focus on how the mentioned methods vary in <strong>exceptions and null handling</strong> and what should we be aware of.</p>
<h2 class="article-heading-introduction">2. Imports</h2>
<p>As the first step, let&#8217;s import the necessary library to our project:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="groovy">implementation("io.projectreactor:reactor-core:3.4.12")
</pre>
<h2 class="article-heading-main">3. Null Handling</h2>
<p>After that, we can start can start practicing with nulls, also known as <em>The Billion Dollar Mistake</em>. Even though the Kotlin provides us a great support in null prevention, they can still occur- either on purpose (hopefully), or by mistake.</p>
<p>Given that, let&#8217;s prepare a function called <em>nullReturningDateFetching</em>:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="kotlin">private fun nullReturningDateFetching(): LocalDateTime? {
    Thread.sleep(500)
    println("GETTING DATE")
    return null
}
</pre>
<p>As a word of explanation- we expect that the above code will cause the current thread to sleep, following by printing <em>GETTING DATE</em> and returning a null value.</p>
<h3 class="article-heading-sub">3.1. Mono.just()</h3>
<p>As the next step, let&#8217;s start with the <strong>Mono.just()</strong> method- just like in the previous article:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="kotlin">private fun monoJustNull(): Mono&lt;LocalDateTime&gt; =
    Mono.just(nullReturningDateFetching())

fun monoJustNullSubscription() {
    val myMono = monoJustNull()
    myMono.subscribe(::println)
    myMono.subscribe(::println)
    myMono.subscribe(::println)
}

fun monoJustNullInstantiation() {
    val myMono = monoJustNull()
}
</pre>
<p>And let&#8217;s run both methods<span class="VIiyi" lang="en"><span class="JLqJ4b ChMk0b" data-language-for-alternatives="en" data-language-to-translate-into="pl" data-phrase-index="0" data-number-of-phrases="1">:</span></span></p>
<pre class="EnlighterJSRAW" data-enlighter-language="raw">// monoJustNullSubscription
GETTING DATE
Exception in thread "main" java.lang.NullPointerException: value

// monoJustNullInstantiation
GETTING DATE
Exception in thread "main" java.lang.NullPointerException: value</pre>
<p>As we can clearly see, both cases completed with the same result- thrown <em>NullPointerException</em>. Whatsoever, if we used an IDE, like IntelliJ, it warned us about <strong>type mismatch</strong>! The reason behind that is pretty straightforward- internally, the <em>Mono.just()</em> method creates a <em>MonoJust</em> class instance, which requires a constructor argument to be <strong>not-null</strong>.</p>
<p>Additionally, we can&#8217;t implement any callback behavior using error-handling operators, like <em>onErrorReturn</em>(). The only possibility to recover in this case would be to wrap the <em>Mono.just(nullReturningDateFetching())</em> with a try-catch block and personally, I find this solution a bit ugly.</p>
<p>Thankfully, if we really need to use the <em>Mono.just()</em> and the value we would like to wrap can be null, a Mono class ships with the <strong>justOrEmpty() </strong>method. Instead of throwing exception, it will emit an <em>onComplete</em> signal, which we can fallback with, for instance, <em>defaultIfEmpty(</em>).</p>
<h3 class="article-heading-sub">3.2. Mono.defer()</h3>
<p>As the next example, let&#8217;s figure out how does the <strong>Mono.defer()</strong> works:</p>
<blockquote><p>Note: the following examples will focus on the subscription part- the reason for this has been covered in the previous article.</p></blockquote>
<pre class="EnlighterJSRAW" data-enlighter-language="kotlin">fun monoDeferNull(): Mono&lt;LocalDateTime&gt; =
    Mono.defer { null }
 
fun monoDeferSubscription() {
    val myMono = monoDeferNull()
    myMono.subscribe(::println)
    myMono.subscribe(::println)
    myMono.subscribe(::println)
}
</pre>
<p>Nextly, let&#8217;s check the result:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="raw">// monoDeferSubscription
// 3x:
[ERROR] (main) Operator called default onErrorDropped - reactor.core.Exceptions$ErrorCallbackNotImplemented: 
java.lang.NullPointerException: The Mono returned by the supplier is null
reactor.core.Exceptions$ErrorCallbackNotImplemented: java.lang.NullPointerException: The Mono returned by the supplier is null
Caused by: java.lang.NullPointerException: The Mono returned by the supplier is null
</pre>
<p>As we might have noticed, the exception seems to be exactly the same. However, it has been caught internally and propagated into the <em>onError</em> signal. For that reason, the number of messages is equal to the number of Subscribers we&#8217;ve created.</p>
<p>Let&#8217;s take a while to see what happens underneath:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="kotlin">try {
    p = Objects.requireNonNull(supplier.get(),
            "The Mono returned by the supplier is null");
}
catch (Throwable e) {
    Operators.error(actual, Operators.onOperatorError(e, actual.currentContext()));
    return;
}
</pre>
<p>We can clearly spot, that this code is responsible for the message we&#8217;ve received. The <em>Operators.error</em> itself is responsible for calling the <em>onError</em> method of our Subscribers.</p>
<p>On the positive side, this behavior allows us to<span class="VIiyi" lang="en"> recover with some error-handling operator, like: </span></p>
<pre class="EnlighterJSRAW" data-enlighter-language="kotlin">fun monoDeferSubscriptionRecover() {
    val myMono =
            monoDeferNull()
                .onErrorReturn(LocalDateTime.MIN)

    myMono.subscribe(::println)
    myMono.subscribe(::println)
    myMono.subscribe(::println)
}
// Result:
-999999999-01-01T00:00
-999999999-01-01T00:00
-999999999-01-01T00:00
</pre>
<h3 class="article-heading-sub">3.3. Mono.fromSupplier()</h3>
<p>Nextly, let&#8217;s check the<strong> Mono.fromSupplier()</strong> method:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="kotlin">fun monoFromSupplierNull(): Mono =
    Mono.fromSupplier { nullReturningDateFetching() }

fun monoFromSupplierSubscription() {
    val myMono = monoFromSupplierNull()
    myMono.subscribe(::println)
    myMono.subscribe(::println)
    myMono.subscribe(::println)
}
</pre>
<p>Similarly, let&#8217;s see the result:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="raw">// monoFromSupplierSubscription
GETTING DATE
GETTING DATE
GETTING DATE
</pre>
<p>This time, no exception has been thrown. In practice, the <strong><em>fromSupplier()</em></strong> method just completes empty when the provided Supplier ( <em>nullReturningDateFetching()</em> in our case) resolves to null. Although we got rid of exception, we need to be aware of that and handle it accordingly. Indeed, the Mono class ships with <em>defaultIfEmpty</em> method, which could be used here<span class="VIiyi" lang="en">.</span></p>
<h3 class="article-heading-sub">3.3. Mono.create()</h3>
<p>As the last example of null handling, let&#8217;s see the <strong>Mono.create()</strong> behavior:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="kotlin">private fun monoCreateNull(): Mono =
    Mono.create { monoSink -&gt; monoSink.success(nullReturningDateFetching()) }

fun monoCreateNullSubscription() {
    val myMono = monoCreateNull()
    myMono.subscribe(::println)
    myMono.subscribe(::println)
    myMono.subscribe(::println)
}
</pre>
<p>And again, let&#8217;s run the above code:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="raw">// monoCreateNullSubscription
GETTING DATE
GETTING DATE
GETTING DATE
</pre>
<p>As we can see, result itself is exactly the same, as in the previous example. However, the reason is slightly different and pretty well explained in the documentation itself:</p>
<blockquote><p>Calling this method [ success(T) ] with a null value will be silently accepted as a call to success() by standard implementations.</p></blockquote>
<h6></h6>
<p>As a result, the silently accepted <em>success()</em> call completes without any value.</p>
<h2 class="article-heading-main">3. Exceptions Handling</h2>
<p>With all of that being explained, we can finally focus on their differences in <strong>exceptions handling</strong>.</p>
<p>Just like previously, let&#8217;s start with another date fetching variant, called <em>exceptionDateFetching</em>:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="kotlin">private fun exceptionDateFetching(): LocalDateTime {
    Thread.sleep(500)
    println("GETTING DATE")
    throw RuntimeException("ERRORS HAPPEN")
}</pre>
<p>Unlike the previous paragraph, let&#8217;s perform a collective comparison of all methods:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="kotlin">private fun monoJustException(): Mono&lt;LocalDateTime&gt; =
Mono.just(exceptionDateFetching())

private fun monoDeferException(): Mono&lt;LocalDateTime&gt; =
    Mono.defer { monoJustException() }

private fun monoFromSupplierException(): Mono&lt;LocalDateTime&gt; =
    Mono.fromSupplier { exceptionDateFetching() }

private fun monoCreateException(): Mono&lt;LocalDateTime&gt; =
    Mono.create { monoSink -&gt; monoSink.success(exceptionDateFetching()) }</pre>
<p>After running all of them, we should see the following result:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="raw">// monoJustExceptionSubscription
GETTING DATE
Exception in thread "main" java.lang.RuntimeException: ERRORS HAPPEN

// monoDeferExceptionSubscription &amp; monoFromSupplierExceptionSubscription &amp; monoCreateExceptionSubscription
// 3x
GETTING DATE
[ERROR] (main) Operator called default onErrorDropped - reactor.core.Exceptions$ErrorCallbackNotImplemented: 
java.lang.RuntimeException: ERRORS HAPPEN
reactor.core.Exceptions$ErrorCallbackNotImplemented: java.lang.RuntimeException: ERRORS HAPPEN
Caused by: java.lang.RuntimeException: ERRORS HAPPEN
</pre>
<p>As we can see- when using the <strong>Mono.just()</strong> method, we have to explicitly make sure that all exceptions are handled within the function responsible for date-time creation. Without that, the exception will be thrown on the instantiation and lead to thread termination.</p>
<p>On the other hand, the rest of the methods will log an error and finally, throw it via <em>Exceptions.bubble(Throwable)</em>. In other words, the exception will be again caught internally and propagated as an <em>onError</em> signal. As we have already seen, this type of signal might be pretty easily handled with onError* methods.</p>
<h2 class="article-heading-main">5. Summary</h2>
<p>And that would be all for this article. I really hope, that you will benefit from this, and the previous tutorial describing differences between the <strong>Mono.just(), defer(), fromSupplier() and create()</strong> methods. Although the Project Reactor is not the most trivial thing in the world, I am 100% sure that you can take advantage of learning it. It will be a pleasure to me to walk you through this process.</p>
<p>Finally, just like always, you can find the source code <a href="https://github.com/codersee-blog/kotlin-reactor-part-2" target="_blank" rel="noopener">here</a>. Moreover, if you would like to ask about anything or you have some suggestions about future topics, please let me know about it in the comment section below, or by using the <a href="https://codersee.com/contact/" target="_blank" rel="noopener noreferrer">contact</a> form.</p>
<p>&nbsp;</p>
<h4 class="article-heading-sub">If you find this material useful, you might be interested in my previous articles:</h4>
<ul>
<li><a href="https://blog.codersee.com/what-is-kotlin-and-why-should-you-learn-it/">What is Kotlin and Why Should You Learn It?</a></li>
<li><a href="https://blog.codersee.com/mono-just-defer-fromsupplier-create-part-1/">Mono.just() vs defer() vs fromSupplier() vs create() &#8211; Part 1</a></li>
<li><a href="https://blog.codersee.com/micronaut-with-mongodb-and-kotlin/">Micronaut with MongoDB and Kotlin</a></li>
</ul>
<p>The post <a href="https://blog.codersee.com/mono-just-defer-fromsupplier-create-part-2/">Mono.just() vs defer() vs fromSupplier() vs create() &#8211; Part 2</a> appeared first on <a href="https://blog.codersee.com">Codersee blog- Kotlin on the backend</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.codersee.com/mono-just-defer-fromsupplier-create-part-2/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Mono.just() vs defer() vs fromSupplier() vs create() &#8211; Part 1</title>
		<link>https://blog.codersee.com/mono-just-defer-fromsupplier-create-part-1/</link>
					<comments>https://blog.codersee.com/mono-just-defer-fromsupplier-create-part-1/#respond</comments>
		
		<dc:creator><![CDATA[Piotr]]></dc:creator>
		<pubDate>Tue, 14 Dec 2021 06:04:13 +0000</pubDate>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Project Reactor]]></category>
		<category><![CDATA[Spring WebFlux]]></category>
		<guid isPermaLink="false">https://codersee.com/?p=1796</guid>

					<description><![CDATA[<p>After reading this first article in a series, you will have a decent understanding of four ways of creating Monos in Project Reactor.</p>
<p>The post <a href="https://blog.codersee.com/mono-just-defer-fromsupplier-create-part-1/">Mono.just() vs defer() vs fromSupplier() vs create() &#8211; Part 1</a> appeared first on <a href="https://blog.codersee.com">Codersee blog- Kotlin on the backend</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<h2 class="wp-block-heading" id="h-1-introduction">1. Introduction</h2>



<p>In the first article of a series related to the <a href="https://projectreactor.io/">Project Reactor</a>, I would like to show you the process of creating Monos with <strong>Mono.just()</strong>, <strong>Mono.defer()</strong>, <strong>Mono.fromSupplier()</strong> and <strong>Mono.create()</strong> methods. After this step by step tutorial, you will have a<strong> decent understanding of each method and differences between them</strong>.</p>



<p>Nonetheless, this is not an introduction to the Project Reactor and to get the most out of this article, <span class="VIiyi" lang="en"><span class="JLqJ4b ChMk0b" data-language-for-alternatives="en" data-language-to-translate-into="pl" data-phrase-index="0" data-number-of-phrases="1">you need to understand at least the basic concepts associated with it. Considering that, I highly recommend their official docs, but if you would be interested in a video explanation, please let me know in the comments section below. </span></span></p>



<p>As the last thing in the introduction I would like welcome you to the Codersee after a long period of time. Last 12 months have been a pretty tough time for me and I had to suspend all of my blog activities. Nevertheless, I am back to blogging bringing you new portion of knowledge and ideas. I am so excited about upcoming months and really hope that you will be too.</p>



<h2 class="wp-block-heading" id="h-2-eager-vs-lazy-evaluation">2. Eager vs Lazy Evaluation</h2>



<p>Before we start considerations about Mono creation, let&#8217;s take a while to understand the difference between <strong>eager</strong> and <strong>lazy</strong> <strong>evaluation</strong>. In general, both terms describe the way expressions are evaluated. With <strong>eager evaluation</strong>, the value will be evaluated immediately, when the instruction has been encountered. In the second case, the process will be delayed until the value is really needed, hence the term- <strong>lazy evaluation</strong>.</p>


<p>[elementor-template id=&#8221;9007393&#8243;]</p>



<h2 class="wp-block-heading" id="h-3-hot-vs-cold-publishers">3. Hot vs Cold Publishers</h2>



<p>Another terms I would like to cover before heading to the clue of this article are <strong>hot and cold publishers</strong>. In Project Reactor all Publishers (like Monos or Fluxes) are considered either one of them. <strong>Cold publishers</strong>, generate new data for each subscription (consider it a bit similar to lazy evaluation), whereas <strong>hot publishers</strong> are independent of subscribers and will produce data anyway (similarity to eagerness).</p>



<p>Undoubtedly, the two above paragraphs are just a brief summary and I highly recommend you do a further investigation. However, I am pretty sure that this knowledge will be sufficient for the purpose of this tutorial.</p>



<h2 class="wp-block-heading" id="h-4-imports">4. Imports</h2>



<p>With that being said, let&#8217;s start by importing necessary library to our project:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="groovy" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">implementation("io.projectreactor:reactor-core:3.4.12")
</pre>



<p>Note: you can find the source code for this article, as always, in our <a href="https://github.com/codersee-blog/kotlin-reactor-part-1">GitHub repository</a>.</p>



<h2 class="wp-block-heading" id="h-5-create-monos">5. Create Monos</h2>



<p>After that, let&#8217;s define what exactly a <strong>Mono</strong> is in terms of Project Reactor? Well, it&#8217;s nothing else than just a specialized Publisher capable of asynchronous emitting of either 1 or 0 element. Fluxes, on the other hand, represent an asynchronous sequence of 0 to N elements.</p>



<h3 class="wp-block-heading" id="h-4-1-mono-just">4.1. Mono.just()</h3>



<p>Provided that, let&#8217;s start everything with an example function called <em><strong>successfulDateFetching</strong></em>:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="kotlin" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">fun successfulDateFetching(): LocalDateTime {
    Thread.sleep(500)
    println("GETTING DATE")
    return LocalDateTime.now()
}
</pre>



<p>As we can see, it will be responsible for three things:</p>



<ul class="wp-block-list">
<li>causing the currently executing thread to sleep,</li>



<li>printing the text to the output,</li>



<li>and finally, returning the current date-time information from the system clock</li>
</ul>



<p>As the next step, let&#8217;s let&#8217;s implement the following <strong><code class="EnlighterJSRAW" data-enlighter-language="kotlin">Mono.just()</code></strong> example:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="kotlin" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">fun monoJust(): Mono&lt;LocalDateTime> =
    Mono.just(successfulDateFetching())

fun monoJustSubscription() {
    val myMono = monoJust()
    myMono.subscribe(::println)
    myMono.subscribe(::println)
    myMono.subscribe(::println)
}

fun monoJustInstantiation() {
    val myMono = monoJust()
}
</pre>



<p>The above code is responsible for creating a new Mono inside the <strong><em>monoJust</em> </strong>function and after that it&#8217;s utilized inside the <strong>monoJustSubscription</strong> or <strong>monoJustInstantiation </strong>methods. Given that, it&#8217;s worth to quote the Reactor documentation here:</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p>Nothing Happens Until You subscribe()</p>
</blockquote>



<p>And that&#8217;s one of the most important things when dealing with Reactor- data do not start pumping into by default. By creating a Mono, we&#8217;re just defining an asynchronous process, but all the magic happens when we tie it to a<strong> Subscriber</strong>. Personally, I would compare that to the process of <strong>class definition</strong>&#8211; just like a class is a simple skeleton with some predefined behavior until we create it&#8217;s <strong>instance</strong>, so here a Mono defines the process of data flow until we subscribe to it.</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p>Note: As always, I highly encourage you to copy and run all of the examples manually, so that<span class="VIiyi" lang="en"><span class="JLqJ4b ChMk0b" data-language-for-alternatives="en" data-language-to-translate-into="pl" data-phrase-index="0" data-number-of-phrases="1"> you could get the most out of this article. </span></span></p>
</blockquote>



<p><span class="VIiyi" lang="en"><span class="JLqJ4b ChMk0b" data-language-for-alternatives="en" data-language-to-translate-into="pl" data-phrase-index="0" data-number-of-phrases="1">With that being said, we expect that that a date-time information will be printed 3 times after running <em>monoJustSubscription</em> and nothing happen in second scenario. Let&#8217;s validate if it&#8217;s true:</span></span></p>



<pre class="EnlighterJSRAW" data-enlighter-language="raw" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">// monoJustSubscription
GETTING DATE
2021-12-08T07:58:22.053724500
2021-12-08T07:58:22.053724500
2021-12-08T07:58:22.053724500

// monoJustInstantiation
GETTING DATE</pre>



<p>As you might have noticed- the result seems to be a bit odd. Why are the printed values exactly the same in the first case and why does the <em>GETTING DATE</em> has been even printed without subscription?</p>



<p>Basically, this is the main difference between a <strong>Mono.just()</strong> and the rest of the methods we&#8217;ll compare in this article. It is a<strong> hot publisher</strong> and the value has been captured at the <strong>instantiation time.</strong> In fact, the<em> successfulDateFetching()</em> has been invoked when we created and instance of Mono- even if we didn&#8217;t subscribe to it! Undeniably, we should be aware of this behavior especially when dealing with multiple subscribers.</p>



<h3 class="wp-block-heading" id="h-4-2-mono-defer">4.2. Mono.defer()</h3>



<p>Thankfully, <strong>Mono.just()</strong> is not the only possible way of creating Monos. Let&#8217;s see what can we do to delay the process of obtaining the date-time with <strong>Mono.defer()</strong>:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="kotlin" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">fun monoDefer(): Mono&lt;LocalDateTime> =
    Mono.defer { monoJust() }

fun monoDeferSubscription() {
    val myMono = monoDefer()
    myMono.subscribe(::println)
    myMono.subscribe(::println)
    myMono.subscribe(::println)
}

fun monoDeferInstantiation() {
    val myMono = monoDefer()
}
</pre>



<p>After that, let&#8217;s run the examples and see the result:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="raw" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">// monoDeferSubscription
GETTING DATE
2021-12-08T09:01:56.457742200
GETTING DATE
2021-12-08T09:01:56.970125600
GETTING DATE
2021-12-08T09:01:57.487761200

// monoDeferInstantiation 

</pre>



<p>This time, we&#8217;ve achieved a real laziness- a <em>successfulDateFetching()</em> was triggered each time a new Subscriber was registered. Moreover, nothing happened, when we just instantiated a Mono. The reason behind this is pretty straightforward- <em>Mono.defer()</em> will supply a target Mono (created by the <em>monoJust()</em>, in our case) to each Subscriber. In fact, the delay between each subscription could be extended to whatever value we would like to, and the printed date-time would be up to date each time.</p>



<p>At this point, we can clearly see that these two methods serve different purposes. If we are dealing with some constant data, or data set, or we are just OK with the data being obtained eagerly, then the <em>Mono.just()</em> should be the choice. On the other hand, if we want the subscriber to receive data calculated at the time of subscription, then the <em>Mono.defer()</em> should be picked to &#8220;wrap&#8221; another Mono.</p>



<h3 class="wp-block-heading" id="h-4-3-mono-fromsupplier">4.3. Mono.fromSupplier()</h3>



<p>Similarly to defer(), we can delay the data evaluation with <strong>Mono.fromSupplier()</strong> case. As the documentation states, it allows us to:</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p>Create a <strong>Mono</strong>, producing its value using the provided <strong>Supplier</strong>. If the Supplier resolves to <strong>null</strong>, the resulting <strong>Mono completes empty</strong>.</p>
</blockquote>



<p>Given that&#8217;s let&#8217;s see the following example:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="kotlin" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">private fun monoFromSupplier(): Mono&lt;LocalDateTime> =
    Mono.fromSupplier { successfulDateFetching() }

fun monoFromSupplierSubscription() {
    val myMono = monoFromSupplier()
    myMono.subscribe(::println)
    myMono.subscribe(::println)
    myMono.subscribe(::println)
}

fun monoFromSupplierInstantiation() {
    val myMono = monoFromSupplier()
}
</pre>



<p>In this case, the output presents as follows:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="raw" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">// monoFromSupplierSubscription
GETTING DATE
2021-12-08T08:33:59.168426800
GETTING DATE
2021-12-08T08:33:59.671269400
GETTING DATE
2021-12-08T08:34:00.187244300

// monoFromSupplierInstantiation

</pre>



<p>We can clearly spot that this, and Mono.defer() execution worked exactly the same. As a word of explanation- both methods serve us to delay (defer) the moment of capturing the value. Most of the time, we ill lean toward them when dealing with external libraries, or another part of the code that we do not have an influence on. To put it simple, our choice will be:</p>



<ul class="wp-block-list">
<li><strong>Mono.defer()</strong>&#8211; when dealing with another library, method or whatever else returning a Mono instance</li>



<li><strong>Mono.fromSupplier()</strong>&#8211; when consuming a simple value being returned from external (not a Mono)</li>
</ul>



<p>Additionally, it&#8217;s worth mentioning that Project Reactor ships with another method called <strong>fromCallable()</strong>, which you might be interested in, as well (but considerations on Supplier and Callable usage won&#8217;t be a part of this article).</p>



<h3 class="wp-block-heading" id="h-4-3-mono-create">4.3. Mono.create()</h3>



<p>Lastly, let&#8217;s have a look at<strong> Mono.create()</strong>. Despite it&#8217;s simple name it is the most advanced way of creating Monos covered in this article. Again, I highly recommend you to check out the official documentation for more thorough exaplanation and examples.</p>



<p>As a word of clarification-<strong> Mono.create()</strong> allows us to deal with internal Mono signals through the <strong>MonoSink&lt;T&gt;</strong> wrapper&#8217;s <strong>create()</strong>, <strong>create(T)</strong> and <strong>error(Throwable)</strong> methods. Similarly, it creates a deffered emitter, I believe the result of the following example is just a formality:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="kotlin" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">fun monoCreate(): Mono =
    Mono.create { monoSink ->
        monoSink.success(successfulDateFetching())
    }

fun monoCreateSubscription() {
    val myMono = monoCreate()
    myMono.subscribe(::println)
    myMono.subscribe(::println)
    myMono.subscribe(::println)
}

fun monoCreateInstantiation() {
    val myMono = monoCreate()
}

// #Result
// monoCreateSubscription
// GETTING DATE 2021-12-08T08:33:59.168426800
// GETTING DATE 2021-12-08T08:33:59.671269400 
// GETTING DATE 2021-12-08T08:34:00.187244300 

// monoCreateInstantiation

</pre>



<p>As we might have noticed, the instantiation process is deferred here, just like when dealing with defer() and fromSupplier() methods. Nevertheless, it is the most advanced method presented in this tutorial which gives us much more control over emitted values and in most cases- it&#8217;s usage won&#8217;t be necessary. On the other hand, it might be a great choice when dealing with some callback-based APIs.</p>



<h2 class="wp-block-heading" id="h-5-conclusion-on-mono-just-vs-defer-vs-fromsupplier-vs-create">5. Conclusion on Mono.just() vs defer() vs fromSupplier() vs create()</h2>



<p>Finally, let&#8217;s have a quick recap on Mono.just() vs defer() vs fromSupplier() vs create():</p>



<ul class="wp-block-list">
<li><strong>Mono.just()</strong>&#8211; value captured at the time of instantiation, each Subscriber will receive the same value</li>



<li><strong>Mono.defer()</strong>&#8211; supplies a target Mono to each Subscriber, so the value will be obtained when subscribing</li>



<li><strong>Mono.fromSupplier()</strong>&#8211; produces a value using provided subscriber on subscribe</li>



<li><strong>Mono.create()</strong>&#8211; creates a deferred emitter, the most advanced method allowing to operate on MonoSink&lt;T&gt;</li>
</ul>



<h2 class="wp-block-heading" id="h-6-summary">6. Summary</h2>



<p>And that’s all for the first article describing differences between Mono&#8217;s just(), defer(), fromSupplier() and create() methods. Additionally, in the next episode, we will focus on differences in null and exceptions handling.</p>



<p>Finally, I really hope that after this read you&#8217;ll get a better understanding of their behavior and use cases. For the source code, please refer to this <a href="https://github.com/codersee-blog/kotlin-reactor-part-1">GitHub repository</a>. Moreover, if you would like to ask about anything or need some more explanation, please do it in the comment section below, or by using the <a href="https://codersee.com/contact/" target="_blank" rel="noopener noreferrer">contact</a> form.</p>
<p>The post <a href="https://blog.codersee.com/mono-just-defer-fromsupplier-create-part-1/">Mono.just() vs defer() vs fromSupplier() vs create() &#8211; Part 1</a> appeared first on <a href="https://blog.codersee.com">Codersee blog- Kotlin on the backend</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.codersee.com/mono-just-defer-fromsupplier-create-part-1/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>

<!--
Performance optimized by W3 Total Cache. Learn more: https://www.boldgrid.com/w3-total-cache/?utm_source=w3tc&utm_medium=footer_comment&utm_campaign=free_plugin

Page Caching using Disk: Enhanced 

Served from: blog.codersee.com @ 2026-05-13 18:16:52 by W3 Total Cache
-->