<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Kamal</title>
    <description>The latest articles on DEV Community by Kamal (@kamalhm).</description>
    <link>https://dev.to/kamalhm</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F76708%2Fa6c2aa35-6ce8-4689-bfea-7c23a22022f4.jpg</url>
      <title>DEV Community: Kamal</title>
      <link>https://dev.to/kamalhm</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/kamalhm"/>
    <language>en</language>
    <item>
      <title>Configuring Connection Pooling with Spring R2DBC</title>
      <dc:creator>Kamal</dc:creator>
      <pubDate>Tue, 04 Jan 2022 15:04:07 +0000</pubDate>
      <link>https://dev.to/kamalhm/configuring-connection-pooling-with-spring-r2dbc-ho6</link>
      <guid>https://dev.to/kamalhm/configuring-connection-pooling-with-spring-r2dbc-ho6</guid>
      <description>&lt;p&gt;This article is the second part of my first article related to Spring Boot R2DBC. If you haven't checked it out, please check out:  &lt;a href="https://kamalhm.dev/reactive-spring-boot-application-with-r2dbc-and-postgresql" rel="noopener noreferrer"&gt;Reactive Spring Boot Application with R2DBC and PostgreSQL&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Connection Pooling
&lt;/h2&gt;

&lt;p&gt;After successfully configuring your Spring Boot with Spring Data R2DBC, you probably want to launch it to production without any performance hiccup. Unfortunately, it's not as straightforward as you would like. You will need to use connection pooling.&lt;/p&gt;

&lt;p&gt;Connection pooling is a way to store and reuse a connection to be reused again later, avoiding the expensive cost of creating a connection for each use.&lt;/p&gt;

&lt;p&gt;Before we implement connection pooling, let's try to do some basic benchmarks to see whether or not it improves our application performance.&lt;/p&gt;

&lt;h2&gt;
  
  
  Playing Around with R2DBC Pooling Performance
&lt;/h2&gt;

&lt;p&gt;There are multiple ways to load test our application, you can even use Apache Benchmark directly from your terminal with the &lt;code&gt;ab&lt;/code&gt; command. But this time, I'd like to explore a tool called &lt;a href="https://k6.10" rel="noopener noreferrer"&gt;K6&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Load Testing with K6
&lt;/h3&gt;

&lt;p&gt;We're testing an API that will insert a hundred record into our database. This is going to be a write-heavy operation to stress the database.&lt;/p&gt;

&lt;h3&gt;
  
  
  Without Connection Pooling
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1633857332864%2FfSp5qR4EU.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1633857332864%2FfSp5qR4EU.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Without connection pooling, we only get 140 requests completed, with the 95th percentile of 2.33s.&lt;/p&gt;

&lt;p&gt;I also noticed that the docker instance responsible for running the database CPU usage spiked dramatically.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1633857567481%2F7-W1vcZMIu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1633857567481%2F7-W1vcZMIu.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Implementing Connection Pooling in Spring Boot R2DBC
&lt;/h2&gt;

&lt;p&gt;In Spring Boot application that use blocking connection to DB such as JDBC connection pooling is usually handled by a popular library called &lt;a href="https://github.com/brettwooldridge/HikariCP" rel="noopener noreferrer"&gt;HikariCP&lt;/a&gt;. Luckily, Spring Data R2DBC already includes connection pooling option that we can use just by enabling it from our &lt;code&gt;properties&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;To enable it, you can add below properties to your &lt;code&gt;application.properties&lt;/code&gt; file and R2DBC will be able to pool the connections to our database! Easy right?&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

spring.r2dbc.pool.enabled=true
spring.r2dbc.pool.initial-size=50
spring.r2dbc.pool.max-size=100


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;As you can probably guess, these properties will initiate the pool with 50 connections ready to use, and when needed it can scale up to maximum of 100 connections. Now then, let's try our benchmark again.&lt;/p&gt;

&lt;h3&gt;
  
  
  With Connection Pooling
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1636298632321%2F0mgyNDQeh-.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1636298632321%2F0mgyNDQeh-.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1636298645768%2FnRAh5aGCD.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1636298645768%2FnRAh5aGCD.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The result is striking. With connection pooling, we completed 480 iterations of the requests, increasing throughput by almost 3.5x and reducing our 95th percentile latency to 668ms, that's an almost 4x latency improvement! When we take a look at the docker instance, the CPU usage also stays comfy at around 76% usage. Enabling connection pooling improves the performance by almost 4x and reduced our database load significantly.&lt;/p&gt;

&lt;h2&gt;
  
  
  Connection Pool Sizing
&lt;/h2&gt;

&lt;p&gt;After seeing an awesome performance improvement above, you might be tempted to try and increase the connection pool even further. After all, if we can get 4x improvement with 100 connection pool, then we should get even better performance with 200 connection pool, right?&lt;/p&gt;

&lt;p&gt;Sorry to burst the bubble but the short answer is no. If you'd like to learn further about connection pool sizing, please refer to this awesome article on pool sizing by the author of HikariCP himself: &lt;a href="https://github.com/brettwooldridge/HikariCP/wiki/About-Pool-Sizing" rel="noopener noreferrer"&gt;https://github.com/brettwooldridge/HikariCP/wiki/About-Pool-Sizing&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;We have learned how easy it is to enable connection pooling on an R2DBC project and its impact on your application performance. So don't forget to set it up whenever you're configuring your application!&lt;/p&gt;

&lt;p&gt;As usual, you can see the source code for the project at: &lt;a href="https://github.com/kamalhm/spring-boot-r2dbc" rel="noopener noreferrer"&gt;https://github.com/kamalhm/spring-boot-r2dbc&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This article is the second part of my first article related to Spring Boot R2DBC. If you haven't checked it out, please check out:  &lt;a href="https://kamalhm.dev/reactive-spring-boot-application-with-r2dbc-and-postgresql" rel="noopener noreferrer"&gt;Reactive Spring Boot Application with R2DBC and PostgreSQL&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Connection Pooling
&lt;/h2&gt;

&lt;p&gt;After successfully configuring your Spring Boot with Spring Data R2DBC, you probably want to launch it to production without any performance hiccup. Unfortunately, it's not as straightforward as you would like. You will need to use connection pooling.&lt;/p&gt;

&lt;p&gt;Connection pooling is a way to store and reuse a connection to be reused again later, avoiding the expensive cost of creating a connection for each use.&lt;/p&gt;

&lt;p&gt;Before we implement connection pooling, let's try to do some basic benchmarks to see whether or not it improves our application performance.&lt;/p&gt;

&lt;h3&gt;
  
  
  Playing Around with R2DBC Pooling Performance
&lt;/h3&gt;

&lt;p&gt;There are multiple ways to load test our application, you can even use Apache Benchmark directly from your terminal with the &lt;code&gt;ab&lt;/code&gt; command. But this time, I'd like to explore a tool called &lt;a href="https://k6.10" rel="noopener noreferrer"&gt;K6&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Load Testing with K6
&lt;/h3&gt;

&lt;p&gt;We're testing an API that will insert a hundred record into our database. This is going to be a write-heavy operation to stress the database.&lt;/p&gt;

&lt;h3&gt;
  
  
  Without Connection Pooling
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1633857332864%2FfSp5qR4EU.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1633857332864%2FfSp5qR4EU.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Without connection pooling, we only get 140 requests completed, with the 95th percentile of 2.33s.&lt;/p&gt;

&lt;p&gt;I also noticed that the docker instance responsible for running the database CPU usage spiked dramatically.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1633857567481%2F7-W1vcZMIu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1633857567481%2F7-W1vcZMIu.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Implementing Connection Pooling in Spring Boot R2DBC
&lt;/h2&gt;

&lt;p&gt;In Spring Boot application that use blocking connection to DB such as JDBC connection pooling is usually handled by a popular library called &lt;a href="https://github.com/brettwooldridge/HikariCP" rel="noopener noreferrer"&gt;HikariCP&lt;/a&gt;. Luckily, Spring Data R2DBC already includes connection pooling option that we can use just by enabling it from our &lt;code&gt;properties&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;To enable it, you can add below properties to your &lt;code&gt;application.properties&lt;/code&gt; file and R2DBC will be able to pool the connections to our database! Easy right?&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

spring.r2dbc.pool.enabled=true
spring.r2dbc.pool.initial-size=50
spring.r2dbc.pool.max-size=100


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;As you can probably guess, these properties will initiate the pool with 50 connections ready to use, and when needed it can scale up to maximum of 100 connections. Now then, let's try our benchmark again.&lt;/p&gt;

&lt;h3&gt;
  
  
  With Connection Pooling
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1636298632321%2F0mgyNDQeh-.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1636298632321%2F0mgyNDQeh-.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1636298645768%2FnRAh5aGCD.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1636298645768%2FnRAh5aGCD.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The result is striking. With connection pooling, we completed 480 iterations of the requests, increasing throughput by almost 3.5x and reducing our 95th percentile latency to 668ms, that's an almost 4x latency improvement! When we take a look at the docker instance, the CPU usage also stays comfy at around 76% usage. Enabling connection pooling improves the performance by almost 4x and reduced our database load significantly.&lt;/p&gt;

&lt;h2&gt;
  
  
  Connection Pool Sizing
&lt;/h2&gt;

&lt;p&gt;After seeing an awesome performance improvement above, you might be tempted to try and increase the connection pool even further. After all, if we can get 4x improvement with 100 connection pool, then we should get even better performance with 200 connection pool, right?&lt;/p&gt;

&lt;p&gt;Sorry to burst the bubble but the short answer is no. If you'd like to learn further about connection pool sizing, please refer to this awesome article on pool sizing by the author of HikariCP himself: &lt;a href="https://github.com/brettwooldridge/HikariCP/wiki/About-Pool-Sizing" rel="noopener noreferrer"&gt;https://github.com/brettwooldridge/HikariCP/wiki/About-Pool-Sizing&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;We have learned how easy it is to enable connection pooling on an R2DBC project and its impact on your application performance. So don't forget to set it up whenever you're configuring your application!&lt;/p&gt;

&lt;p&gt;As usual, you can see the source code for the project at: &lt;a href="https://github.com/kamalhm/spring-boot-r2dbc" rel="noopener noreferrer"&gt;https://github.com/kamalhm/spring-boot-r2dbc&lt;/a&gt;&lt;/p&gt;

</description>
      <category>java</category>
      <category>spring</category>
      <category>database</category>
      <category>r2dbc</category>
    </item>
    <item>
      <title>Reactive Spring Boot Application with R2DBC and PostgreSQL</title>
      <dc:creator>Kamal</dc:creator>
      <pubDate>Fri, 18 Jun 2021 14:00:11 +0000</pubDate>
      <link>https://dev.to/kamalhm/reactive-spring-boot-application-with-r2dbc-and-postgresql-o37</link>
      <guid>https://dev.to/kamalhm/reactive-spring-boot-application-with-r2dbc-and-postgresql-o37</guid>
      <description>&lt;h2&gt;
  
  
  Reactive Spring Boot Application with R2DBC and PostgreSQL
&lt;/h2&gt;

&lt;p&gt;Originally published on &lt;a href="https://medium.com/bliblidotcom-techblog/reactive-spring-boot-application-with-r2dbc-and-postgresql-849fc7811135" rel="noopener noreferrer"&gt;Medium&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Also available on my &lt;a href="https://kamalhm.dev/posts/reactive-spring-boot-with-r2dbc" rel="noopener noreferrer"&gt;blog&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Reactive Application
&lt;/h2&gt;

&lt;p&gt;Reactive application is getting more popular with the rise of microservice architecture. To utilize the full potential of a reactive system, it is recommended to make all of our systems reactive. However, making a fully reactive application is still quite a challenge in the JVM world, because JDBC (Java Database Connectivity) is a &lt;strong&gt;synchronous&lt;/strong&gt;, and &lt;strong&gt;blocking&lt;/strong&gt; API for connecting to relational databases, which most applications use to store their data.&lt;/p&gt;

&lt;p&gt;To address this issue, Pivotal (the company behind the Spring framework) led a community effort to create an asynchronous way of connecting to the database. This project is now called R2DBC (Reactive Relational Database Connectivity). After the R2DBC initiatives, the Spring team decided to support R2DBC in the Spring ecosystem, and thus &lt;a href="https://spring.io/projects/spring-data-r2dbc" rel="noopener noreferrer"&gt;Spring Data R2DBC&lt;/a&gt; was born.&lt;/p&gt;

&lt;h2&gt;
  
  
  Project Setup
&lt;/h2&gt;

&lt;p&gt;Let’s have a look at how we can create a fully reactive application using Spring Boot and Spring Data R2DBC. We can scaffold the project using the handy &lt;a href="https://start.spring.io/" rel="noopener noreferrer"&gt;Spring Initializr&lt;/a&gt;, we will use Java 8, Maven, and Jar as our packaging.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F22r7ig742edblq165mpg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F22r7ig742edblq165mpg.png" alt="spring-initializr"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Three dependencies must be included:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Spring Data R2DBC&lt;/li&gt;
&lt;li&gt;PostgreSQL Driver&lt;/li&gt;
&lt;li&gt;Spring Reactive Web&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Lombok and Spring Boot DevTools are not mandatory, but they do help ease a lot of pain when developing Spring applications. If you don’t know what are their use case, I’d highly recommend taking a look at their documentation.&lt;/p&gt;

&lt;p&gt;After opening the project, we will be greeted by the usual Spring Boot main class like this&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;

&lt;span class="nd"&gt;@SpringBootApplication&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ReactivePostgresApplication&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

  &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;SpringApplication&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;ReactivePostgresApplication&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;To start, we will create our POJO class representing a very simple Member&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;

&lt;span class="nd"&gt;@Value&lt;/span&gt;
&lt;span class="nd"&gt;@Builder&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Member&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="nd"&gt;@Id&lt;/span&gt;
  &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;Long&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The @Value and &lt;a class="mentioned-user" href="https://dev.to/builder"&gt;@builder&lt;/a&gt; is an annotation from Lombok, they generate a setter and getter, and a bunch of other things to make our code less stuffed with boilerplate code.&lt;/p&gt;

&lt;h2&gt;
  
  
  R2DBC Repository
&lt;/h2&gt;

&lt;p&gt;Creating a repository is also straightforward, still very familiar with what we used to do in other Spring Data frameworks, in this example we will extend our interface with R2dbcRepository.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;

&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;MemberRepository&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;R2dbcRepository&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Member&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Long&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="nc"&gt;Mono&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Member&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;findByName&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;On line 2, we create a custom method that will query the member data by name. If you want to see a snippet of what this repository could do, you can check this &lt;a href="https://docs.spring.io/spring-data/r2dbc/docs/1.2.2/reference/html/#r2dbc.repositories.queries" rel="noopener noreferrer"&gt;documentation&lt;/a&gt; for more information. In this R2DBC repository, the custom method is not returning Member directly, but it’s wrapped in Mono. Every method in this repository will use either Mono or Flux. This is in line with what the &lt;a href="https://projectreactor.io/" rel="noopener noreferrer"&gt;Project Reactor&lt;/a&gt; uses, so we have full compatibility with reactive API.&lt;/p&gt;

&lt;p&gt;Not only R2dbcRepository, in Spring Data R2DBC we have the option to extends the interface with one of these two options:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;ReactiveCrudRepository, for your generic CRUD repository and,&lt;/li&gt;
&lt;li&gt;ReactiveSortingRepository for an additional sorting function.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;You can choose any of these options, depending on your use case.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F662teool11e63p7xmvex.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F662teool11e63p7xmvex.png" alt="r2dbc-repository-diagram"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next, let’s have a look at how we can implement a reactive controller&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;

&lt;span class="nd"&gt;@RestController&lt;/span&gt;
&lt;span class="nd"&gt;@RequestMapping&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"/api/member"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="nd"&gt;@RequiredArgsConstructor&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MemberController&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

  &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;MemberRepository&lt;/span&gt; &lt;span class="n"&gt;memberRepository&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

  &lt;span class="nd"&gt;@GetMapping&lt;/span&gt;
  &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;Flux&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Member&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;getAll&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;memberRepository&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;findAll&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;

  &lt;span class="nd"&gt;@GetMapping&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"/{name}"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
  &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;Mono&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Member&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;getOne&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nd"&gt;@PathVariable&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;memberRepository&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;findByName&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;For this example, we’ll create 2 separate endpoints that will use Mono and Flux:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;On method getAll, we use the repository that we created earlier to get all the data in the database, because we will get more than 1 data, the returned data is wrapped in Flux.&lt;/li&gt;
&lt;li&gt;On method getOne, we request for a single piece of data, for this case we wrap the returned data in Mono.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;We’re almost done now. Now that we have set up the API, all we need to do is connect the application to our database. To do this, we’ll need to add these two properties in our application.properties file.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight properties"&gt;&lt;code&gt;

&lt;span class="py"&gt;spring.r2dbc.url&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;r2dbc:postgresql://postgres@localhost:5432/reactive&lt;/span&gt;
&lt;span class="py"&gt;logging.level.org.springframework.r2dbc&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;DEBUG&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The first line will tell spring to connect to a local database with a database name of reactive with r2dbc as its connection protocol.&lt;/p&gt;

&lt;p&gt;The second line is a debugging properties so we can see exactly the queries that are running inside our application.&lt;/p&gt;

&lt;p&gt;Next, we need to create a schema.sql file to initialize our database table, we can do that using this query:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;

&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;IF&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;EXISTS&lt;/span&gt; &lt;span class="n"&gt;member&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="nb"&gt;SERIAL&lt;/span&gt; &lt;span class="k"&gt;PRIMARY&lt;/span&gt; &lt;span class="k"&gt;KEY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="nb"&gt;TEXT&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;We’re saving this inside our resources folder.&lt;/p&gt;

&lt;p&gt;One last step, because Spring Data R2DBC doesn’t support auto initializing the database with our schema, we have to manually execute this query when we’re starting our application, this is one of the ways to do it:&lt;/p&gt;

&lt;p&gt;We can create a bean on our main application to execute schema.sql whenever we run our application.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;

&lt;span class="nd"&gt;@Bean&lt;/span&gt;
&lt;span class="nc"&gt;ConnectionFactoryInitializer&lt;/span&gt; &lt;span class="nf"&gt;initializer&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nd"&gt;@Qualifier&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"connectionFactory"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nc"&gt;ConnectionFactory&lt;/span&gt; &lt;span class="n"&gt;connectionFactory&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="nc"&gt;ConnectionFactoryInitializer&lt;/span&gt; &lt;span class="n"&gt;initializer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ConnectionFactoryInitializer&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
  &lt;span class="n"&gt;initializer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setConnectionFactory&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;connectionFactory&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
  &lt;span class="nc"&gt;ResourceDatabasePopulator&lt;/span&gt; &lt;span class="n"&gt;resource&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
      &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;ResourceDatabasePopulator&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ClassPathResource&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"schema.sql"&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
  &lt;span class="n"&gt;initializer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setDatabasePopulator&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;resource&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;initializer&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Now we can finally run our application. When we see into the log, we can see that the application executed our schema.sql.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

202-01-07 12:33:49.037 DEBUG 37404 --- [actor-tcp-nio-1] o.s.r2dbc.connection.init.ScriptUtils    : Executing SQL script from class path resource [schema.sql]
2021-01-07 12:33:49.088 DEBUG 37404 --- [actor-tcp-nio-1] o.s.r2dbc.connection.init.ScriptUtils    : 0 returned as update count for SQL: CREATE TABLE IF NOT EXISTS member ( id SERIAL PRIMARY KEY, name TEXT NOT NULL )


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;From our example above, we created 2 GET endpoints:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;/api/member&lt;/code&gt; to get all of our member’s data&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/api/member/{name}&lt;/code&gt; to get a specific member’s data&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;When we hit the endpoint of our API to get all member on localhost:8080/api/member we can see that the R2DBC executed this SQL&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

2021-01-07 12:35:21.823 DEBUG 37404 --- [ctor-http-nio-3] o.s.r2dbc.core.DefaultDatabaseClient     : Executing SQL statement [SELECT member.* FROM member]


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;and when we do a request on &lt;code&gt;localhost:8080/api/member/{memberName}&lt;/code&gt;, the app shows that we’re executing a query to get a single record.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

2021-01-07 12:39:24.956 DEBUG 37404 --- [ctor-http-nio-3] o.s.r2dbc.core.DefaultDatabaseClient     : Executing SQL statement [SELECT member.id, member.name FROM member WHERE member.name = $1]


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;At this point, we have successfully created a fully reactive application with Spring Data R2DBC, with PostgreSQL as our relational database.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Creating a fully reactive Spring application is easier with the help of Spring Data R2DBC. The process is not too different than what we’re used to and we can still use the same Repository that we use in a non-reactive database. It is not as smooth as it seems though, this is a very basic example application, not a production scale application with all its complex requirements. So, depending on your use case, you might not be able to use Spring Data R2DBC yet.&lt;/p&gt;

&lt;p&gt;There is also a difference in how to fine-tune your database because we don’t use JDBC anymore, one of the examples is connection pooling. We might be familiar with &lt;a href="https://github.com/brettwooldridge/HikariCP" rel="noopener noreferrer"&gt;HikariCP&lt;/a&gt; for our database connection pooling, but on the reactive side HikariCP is not available. To use connection pooling we can use &lt;a href="https://github.com/r2dbc/r2dbc-pool" rel="noopener noreferrer"&gt;R2DBC Pool&lt;/a&gt; instead. All in all, R2DBC is a promising technology, allowing us to have a fully reactive application.&lt;/p&gt;

&lt;p&gt;Even though there are a lot of unknowns, it’s still worth exploring!&lt;/p&gt;

&lt;p&gt;If you want to see the full source code, here’s the link to the &lt;a href="https://github.com/kamalhm/spring-boot-r2dbc" rel="noopener noreferrer"&gt;repository&lt;/a&gt;&lt;br&gt;
 is a promising technology, allowing us to have a fully reactive application.&lt;/p&gt;

&lt;p&gt;Even though there are a lot of unknowns, it’s still worth exploring!&lt;/p&gt;

&lt;p&gt;If you want to see the full source code, here’s the link to the &lt;a href="https://github.com/kamalhm/spring-boot-r2dbc" rel="noopener noreferrer"&gt;repository&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
