<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Kamal Mahmud]]></title><description><![CDATA[An eager and curious software engineer.]]></description><link>https://kamalhm.dev</link><generator>RSS for Node</generator><lastBuildDate>Sun, 12 Apr 2026 09:33:14 GMT</lastBuildDate><atom:link href="https://kamalhm.dev/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[My Manual Way of Setting Up MacBook Pro M1 for Software Development]]></title><description><![CDATA[My Manual Way of Setting Up MacBook Pro M1 for Software Development
I’m setting up a new Macbook Pro (16 inch, 2021 M1 Pro), and I’d like to document what I do for my own reference and hopefully will help others too. I don’t have dotfiles because so ...]]></description><link>https://kamalhm.dev/my-manual-way-of-setting-up-macbook-pro-m1-for-software-development</link><guid isPermaLink="true">https://kamalhm.dev/my-manual-way-of-setting-up-macbook-pro-m1-for-software-development</guid><category><![CDATA[software development]]></category><category><![CDATA[macbook]]></category><category><![CDATA[Java]]></category><category><![CDATA[setup]]></category><dc:creator><![CDATA[Kamal Mahmud]]></dc:creator><pubDate>Mon, 03 Oct 2022 04:25:34 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/unsplash/Jx-UX9zVdKk/upload/v1664770915315/LvhV2xWgw.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h1 id="heading-my-manual-way-of-setting-up-macbook-pro-m1-for-software-development">My Manual Way of Setting Up MacBook Pro M1 for Software Development</h1>
<p>I’m setting up a new Macbook Pro (16 inch, 2021 M1 Pro), and I’d like to document what I do for my own reference and hopefully will help others too. I don’t have <code>dotfiles</code> because so far I don’t really use a lot of aliases or custom configuration.</p>
<p>If you know a way to automate some of this steps, I’m looking mostly for a way to automate all the Settings part so I don’t need to rely on the UI, please let me know!</p>
<h2 id="heading-first-steps">First steps</h2>
<ul>
<li>OhMyZsh: <code>sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)"</code></li>
<li>Homebrew: <code>/bin/bash -c "$(curl -fsSL [https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh](https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh))"</code></li>
<li>Generate SSH key: <code>ssh-keygen -t ed25519 -C "your_email@example.com"</code></li>
</ul>
<h2 id="heading-brewfile">Brewfile</h2>
<p>If you don’t have one, you should do a backup of all your installed packages on your previous Mac by running the command <code>brew bundle dump</code>. This will generate a <code>Brewfile</code> which you can use to reinstall all the packages you have installed.</p>
<p>Here is how mine looks like:</p>
<pre><code class="lang-bash">tap <span class="hljs-string">"homebrew/bundle"</span>
tap <span class="hljs-string">"homebrew/cask"</span>
tap <span class="hljs-string">"homebrew/cask-fonts"</span>
tap <span class="hljs-string">"homebrew/core"</span>
tap <span class="hljs-string">"homebrew/services"</span>
brew <span class="hljs-string">"bat"</span>
brew <span class="hljs-string">"colima"</span>
brew <span class="hljs-string">"docker"</span>
brew <span class="hljs-string">"docker-compose"</span>
brew <span class="hljs-string">"exa"</span>
brew <span class="hljs-string">"gh"</span>
brew <span class="hljs-string">"jenv"</span>
brew <span class="hljs-string">"jq"</span>
brew <span class="hljs-string">"mas"</span>
brew <span class="hljs-string">"ripgrep"</span>
brew <span class="hljs-string">"teleport"</span>
cask <span class="hljs-string">"devutils"</span>
cask <span class="hljs-string">"disk-inventory-x"</span>
cask <span class="hljs-string">"font-fira-code"</span>
cask <span class="hljs-string">"imageoptim"</span>
cask <span class="hljs-string">"insomnia"</span>
cask <span class="hljs-string">"iterm2"</span>
cask <span class="hljs-string">"jetbrains-toolbox"</span>
cask <span class="hljs-string">"monodraw"</span>
cask <span class="hljs-string">"mos"</span>
cask <span class="hljs-string">"obsidian"</span>
cask <span class="hljs-string">"raycast"</span>
cask <span class="hljs-string">"rectangle"</span>
cask <span class="hljs-string">"telegram-desktop"</span>
cask <span class="hljs-string">"tunnelblick"</span>
cask <span class="hljs-string">"visual-studio-code"</span>
cask <span class="hljs-string">"vlc"</span>
cask <span class="hljs-string">"whatsapp"</span>
cask <span class="hljs-string">"zoom"</span>
mas <span class="hljs-string">"Amphetamine"</span>, id: 937984704
mas <span class="hljs-string">"Hand Mirror"</span>, id: 1502839586
mas <span class="hljs-string">"Outline"</span>, id: 1356178125
</code></pre>
<p>To install, run <code>brew bundle</code> on the directory where the <code>Brewfile</code> is located.</p>
<h2 id="heading-login-to-your-accounts">Login to your accounts</h2>
<p> You’ll probably use these for authenticating to other services:</p>
<ul>
<li>Gmail</li>
<li>Github</li>
</ul>
<h2 id="heading-terminal">Terminal</h2>
<p>I really like iTerm2 for my everyday terminal. I can’t really feel the difference of speed between the default terminal and iTerm2, I just like some of its features and as a bonus, it’s not slow either.</p>
<p>The only other preferences I’d like to change is to show CPU, RAM, and Network usage on the status bar.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1664770423904/DDeG4TcVI.png" alt="image.png" /></p>
<h2 id="heading-java-setup">Java setup</h2>
<p>I use SDKMAN to setup all my JDK related needs</p>
<p>Install:</p>
<p><code>curl -s "https://get.sdkman.io" | bash</code></p>
<p>then <code>sdk install java</code> to install the latest LTS Java version.</p>
<h2 id="heading-docker">Docker</h2>
<p>I’ve used Docker Desktop for a while but I’m trying the alternative, which is <a target="_blank" href="https://github.com/abiosoft/colima/">Colima</a>. I’m liking it so far, and not having access to the GUI also helps me remembering most used docker commands.</p>
<p>Steps:</p>
<p><code>brew install colima</code></p>
<p><code>brew install docker</code></p>
<p><code>brew install docker-compose</code></p>
<p><code>colima start</code></p>
<p><code>docker ps</code></p>
<p>Notes: if you followed my Brewfile then colima will already be installed and you can just run <code>colima start</code> to start using Docker.</p>
<h2 id="heading-mouse">Mouse</h2>
<p>I’m using Logitech MX Master 2S right now so I’ll need <a target="_blank" href="https://download01.logi.com/web/ftp/pub/techsupport/options/options_installer.zip">Logitech Options</a>.</p>
<h3 id="heading-disabling-mouse-acceleration">Disabling mouse acceleration</h3>
<p>I don’t like the mouse acceleration Mac has when you’re using mouse because I’m a gamer and I’m used to not have any acceleration. Here’s how to disable it:</p>
<ul>
<li>Set tracking speed to zero on Mouse setting</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1664770466604/bj-KDA7dc.png" alt="image.png" /></p>
<ul>
<li>Set the pointer speed on Logitech Options</li>
</ul>
<p>With this configuration, make sure you run Logitech Options on startup otherwise your mouse will be pretty slow.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1664770481610/wgmLuouvV.png" alt="image.png" /></p>
<p>I also like to enlarge my cursor size because it’s so helpful when presenting and I’ve never lost sight of my cursor ever again.</p>
<h3 id="heading-smooth-scrolling">Smooth scrolling</h3>
<p>The default scroll behavior when using mouse is janky, and using the built in smooth scroll from Logitech Options is not good enough so I turn to <a target="_blank" href="https://github.com/Caldis/Mos">Mos</a> to enable smooth scrolling.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1664770544002/yvIT1ka8K.png" alt="image.png" /></p>
<h2 id="heading-spotlight-alternative-raycast">Spotlight alternative: Raycast</h2>
<p><a target="_blank" href="https://www.raycast.com/">Raycast</a> is a new challenger to the well-known Alfred, I haven’t use Alfred extensively when I switched to Raycast, but so far I’m enjoying it. They have various features to helps you be productive and it’s very extendable. </p>
<p>The Floating Notes in particular has been very helpful for writing a quick note while I’m in a meeting or saving that user info that you need to debug your application.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1664770555655/Q8eFgOlSP.png" alt="image.png" /></p>
<h2 id="heading-settings">Settings</h2>
<ul>
<li>Touchpad<ul>
<li>Enable one click</li>
<li>Disable dictionary lookup</li>
</ul>
</li>
<li>Dock<ul>
<li>Auto hide and show</li>
<li>Disable show recent items</li>
<li>Clear up everything except: Finder, System Preferences</li>
</ul>
</li>
<li>Siri<ul>
<li>Disable it</li>
</ul>
</li>
<li>Sound<ul>
<li>Disable "Play user interface sound effects"</li>
</ul>
</li>
<li>Keyboard<ul>
<li>Key repeat → Fast</li>
<li>Delay until repeat → Short</li>
<li>Text<ul>
<li>Disable "Correct spelling automatically"</li>
<li>Disable "Capitalize words automatically"</li>
<li>Disable "Add period with double-space"</li>
<li>Disable "Use smart quotes and dashes"</li>
</ul>
</li>
<li>Shortcuts<ul>
<li>Screenshots: Copy picture of selected area as a file → Option + Shift + S
I set the screenshot button to be the same as Windows because I switch between them quite often.</li>
<li>Keyboard: Add Keyboard shortcuts to use Command + Esc to switch between app
I’m currently using 65% keyboard so I don’t have the Tilde key to press easily, so I mapped it to Esc key.</li>
</ul>
</li>
</ul>
</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1664770571405/3rz90Hxyq.png" alt="image.png" /></p>
<h2 id="heading-git-config">Git config</h2>
<p>If you like to tinker around with side projects in your spare time, you will often needs to commit something with your personal Github account. Changing the credentials when switching to side project is tiresome, so here’s how I managed to do it:</p>
<ul>
<li>Global git config on <code>~/.gitconfig</code></li>
</ul>
<pre><code class="lang-bash">[user]
    name = Kamal Mahmud
    email = kamalhm1997@gmail.com

[pull]
    rebase = <span class="hljs-literal">true</span>

[includeIf <span class="hljs-string">"gitdir:~/work/"</span>]
    path = ~/work/.gitconfig
</code></pre>
<ul>
<li>Git config on work folder <code>~/work</code></li>
</ul>
<pre><code class="lang-bash">[user]
  email = kamal.mahmud@orgs.com
</code></pre>
<p>Reference: <a target="_blank" href="https://stackoverflow.com/questions/4220416/can-i-specify-multiple-users-for-myself-in-gitconfig/43654115#43654115">https://stackoverflow.com/questions/4220416/can-i-specify-multiple-users-for-myself-in-gitconfig/43654115#43654115</a></p>
]]></content:encoded></item><item><title><![CDATA[Configuring Connection Pool with Spring R2DBC]]></title><description><![CDATA[Edit on 10 March 2022:

Edited the article and example code to use five initial connections and a maximum of ten connections to give a better example of connection pool sizing.

This article is the second part of my first article related to Spring Bo...]]></description><link>https://kamalhm.dev/configuring-connection-pool-with-spring-r2dbc</link><guid isPermaLink="true">https://kamalhm.dev/configuring-connection-pool-with-spring-r2dbc</guid><category><![CDATA[Java]]></category><category><![CDATA[Spring]]></category><category><![CDATA[Springboot]]></category><category><![CDATA[Databases]]></category><category><![CDATA[PostgreSQL]]></category><dc:creator><![CDATA[Kamal Mahmud]]></dc:creator><pubDate>Tue, 04 Jan 2022 14:56:36 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1633857332864/fSp5qR4EU.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Edit on 10 March 2022:</p>
<ul>
<li>Edited the article and example code to use five initial connections and a maximum of ten connections to give a better example of connection pool sizing.</li>
</ul>
<p>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:  <a target="_blank" href="https://kamalhm.dev/reactive-spring-boot-application-with-r2dbc-and-postgresql">Reactive Spring Boot Application with R2DBC and PostgreSQL</a></p>
<h2 id="heading-connection-pooling">Connection Pooling</h2>
<p>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.</p>
<p>Connection pooling is a way to store and reuse a connection to be reused later, avoiding the expensive cost of creating a connection for each use.</p>
<p>Before we implement connection pooling, let's try to do some basic benchmarks to see whether or not it improves our application performance.</p>
<h3 id="heading-playing-around-with-r2dbc-pooling-performance">Playing Around with R2DBC Pooling Performance</h3>
<p>There are multiple ways to load test our application, you can even use Apache Benchmark directly from your terminal with the <code>ab</code> command. But this time, I'd like to explore a tool called <a target="_blank" href="https://k6.10">K6</a>.</p>
<h3 id="heading-load-testing-with-k6">Load Testing with K6</h3>
<p>We're testing an API to insert a hundred records into our database. This API is going to be a write-heavy operation to stress the database.</p>
<h3 id="heading-without-connection-pooling">Without Connection Pooling</h3>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1633857332864/fSp5qR4EU.png" alt="image" /></p>
<p>Without connection pooling, we only get 140 requests completed, with the 95th percentile of 2.33s.</p>
<p>I also noticed that the docker instance responsible for running the database CPU usage spiked dramatically.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1633857567481/7-W1vcZMIu.png" alt="image" /></p>
<h2 id="heading-implementing-connection-pooling-in-spring-boot-r2dbc">Implementing Connection Pooling in Spring Boot R2DBC</h2>
<p>In Spring Boot applications that use blocking connection to a database such as JDBC, connection pooling is usually handled by a popular library called <a target="_blank" href="https://github.com/brettwooldridge/HikariCP">HikariCP</a>. Luckily, Spring Data R2DBC already includes a connection pooling option that we can use just by enabling it from our <code>properties</code>.</p>
<p>To enable it, you can add the below properties to your <code>application.properties</code> file, and R2DBC will be able to pool the connections to our database! Easy right?</p>
<pre><code class="lang-other">spring.r2dbc.pool.enabled=true
spring.r2dbc.pool.initial-size=5
spring.r2dbc.pool.max-size=10
</code></pre>
<p>As you can probably guess, these properties will initiate the pool with five connections ready to use, and when needed, it can scale up to a maximum of 10 connections. Now then, let's try our benchmark again.</p>
<h3 id="heading-with-connection-pooling">With Connection Pooling</h3>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1636298632321/0mgyNDQeh-.png" alt="image" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1636298645768/nRAh5aGCD.png" alt="image" /></p>
<p>The result is striking. We completed 480 iterations of the requests with connection pooling, increasing throughput by almost 3.5x and reducing our 95th percentile latency to 668ms. That's an almost 4x latency improvement! When we look at the docker instance, the CPU usage also stays comfy at around 76% usage. Enabling connection pooling improved the performance by almost 4x and reduced our database load significantly.</p>
<h2 id="heading-connection-pool-sizing">Connection Pool Sizing</h2>
<p>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 ten connections, we should get even better performance with a 20 connection pool. Or at least that's what we expect. But sorry to burst the bubble. The short answer is no. </p>
<p>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: <a target="_blank" href="https://github.com/brettwooldridge/HikariCP/wiki/About-Pool-Sizing">https://github.com/brettwooldridge/HikariCP/wiki/About-Pool-Sizing</a></p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>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!</p>
<p>As usual, you can see the source code for the project at <a target="_blank" href="https://github.com/kamalhm/spring-boot-r2dbc">https://github.com/kamalhm/spring-boot-r2dbc</a></p>
]]></content:encoded></item><item><title><![CDATA[Reactive Spring Boot Application with R2DBC and PostgreSQL]]></title><description><![CDATA[*note: the example repository has been updated with Java 17 and Spring Boot 3
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 o...]]></description><link>https://kamalhm.dev/reactive-spring-boot-application-with-r2dbc-and-postgresql</link><guid isPermaLink="true">https://kamalhm.dev/reactive-spring-boot-application-with-r2dbc-and-postgresql</guid><category><![CDATA[Java]]></category><category><![CDATA[Spring]]></category><category><![CDATA[Springboot]]></category><dc:creator><![CDATA[Kamal Mahmud]]></dc:creator><pubDate>Sun, 10 Jan 2021 18:44:41 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1628322408225/KhCc-zfvZ.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>*note: the example repository has been updated with Java 17 and Spring Boot 3</p>
<p>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.</p>
<p>However, making a fully reactive application is still quite a challenge in the JVM world, because JDBC (Java Database Connectivity) is a **synchronous, **and **blocking **API for connecting to relational databases, which most applications use to store their data.</p>
<p>To address this issue, Pivotal (the company behind the Spring framework) led a community effort to create an <strong>asynchronous</strong> way of connecting to the database, this project is now called R2DBC (Reactive Relational Database Connectivity).</p>
<p>After the R2DBC initiatives, the Spring team decided to support R2DBC in the Spring ecosystem, and thus <a target="_blank" href="https://spring.io/projects/spring-data-r2dbc">Spring Data R2DBC</a> was born.</p>
<h2 id="heading-project-setup">Project setup</h2>
<p>Let’s have a look at how we can create a fully reactive application using Spring Boot and Spring Data R2DBC.</p>
<p>We can scaffold the project using the handy Spring Initializr (<a target="_blank" href="https://start.spring.io/">https://start.spring.io/</a>), we will use Java 8, Maven, and Jar as our packaging.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1628322404938/HBZT6gQB5f.png" alt /></p>
<p>Three dependencies must be included:</p>
<ol>
<li><p>Spring Data R2DBC</p>
</li>
<li><p>PostgreSQL Driver</p>
</li>
<li><p>Spring Reactive Web</p>
</li>
</ol>
<p>Lombok and Spring Boot DevTools is 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.</p>
<p>After opening the project, we will be greeted by the usual Spring Boot main class like this</p>
<pre><code class="lang-java"><span class="hljs-meta">@SpringBootApplication</span>
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ReactivePostgresApplication</span> </span>{

  <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">main</span><span class="hljs-params">(String[] args)</span> </span>{
    SpringApplication.run(ReactivePostgresApplication.class, args);
  }
}
</code></pre>
<p>To start, we will create our POJO class representing a very simple Member</p>
<pre><code class="lang-java"><span class="hljs-meta">@Value</span>
<span class="hljs-meta">@Builder</span>
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Member</span> </span>{
  <span class="hljs-meta">@Id</span>
  <span class="hljs-keyword">private</span> Long id;
  <span class="hljs-keyword">private</span> String name;
}
</code></pre>
<p>The <code>@Value</code> and <code>@Builder</code> 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.</p>
<h2 id="heading-r2dbc-repository">R2DBC repository</h2>
<p>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 <code>R2dbcRepository</code>.</p>
<pre><code class="lang-java"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">interface</span> <span class="hljs-title">MemberRepository</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">R2dbcRepository</span>&lt;<span class="hljs-title">Member</span>, <span class="hljs-title">Long</span>&gt; </span>{
  <span class="hljs-function">Mono&lt;Member&gt; <span class="hljs-title">findByName</span><span class="hljs-params">(String name)</span></span>;
}
</code></pre>
<p>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 <a target="_blank" href="https://docs.spring.io/spring-data/r2dbc/docs/1.2.2/reference/html/#r2dbc.repositories.queries">documentation</a> for more information. In this R2DBC repository, the custom method is not returning <code>Member</code> directly, but it’s wrapped in <code>Mono</code>. Every method in this repository will use either <code>Mono</code> or <code>Flux</code>. This is in line with what the <a target="_blank" href="https://projectreactor.io/">Project Reactor</a> uses, so we have full compatibility with reactive API.</p>
<p>Not only <code>R2dbcRepository</code>, in Spring Data R2DBC we have the option to extends the interface with one of these two options:</p>
<ol>
<li><p><code>ReactiveCrudRepository</code>, for your generic CRUD repository and,</p>
</li>
<li><p><code>ReactiveSortingRepository</code> for an additional sorting function.</p>
</li>
</ol>
<p>You can choose any of these options, depending on your use case.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1628322406547/NLPKJSYq5.png" alt="R2dbc Repository Class Diagrams" /></p>
<p><em>R2dbc Repository Class Diagrams</em></p>
<p>Next, let’s have a look at how we can implement a reactive controller</p>
<pre><code class="lang-java"><span class="hljs-meta">@RestController</span>
<span class="hljs-meta">@RequestMapping(value = "/api/member")</span>
<span class="hljs-meta">@RequiredArgsConstructor</span>
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">MemberController</span> </span>{

  <span class="hljs-keyword">private</span> <span class="hljs-keyword">final</span> MemberRepository memberRepository;

  <span class="hljs-meta">@GetMapping</span>
  <span class="hljs-function"><span class="hljs-keyword">public</span> Flux&lt;Member&gt; <span class="hljs-title">getAll</span><span class="hljs-params">()</span> </span>{
    <span class="hljs-keyword">return</span> memberRepository.findAll();
  }

  <span class="hljs-meta">@GetMapping(value = "/{name}")</span>
  <span class="hljs-function"><span class="hljs-keyword">public</span> Mono&lt;Member&gt; <span class="hljs-title">getOne</span><span class="hljs-params">(<span class="hljs-meta">@PathVariable</span> String name)</span> </span>{
    <span class="hljs-keyword">return</span> memberRepository.findByName(name);
  }
}
</code></pre>
<p>For this example, we’ll create 2 separate endpoints that will use <code>Mono</code> and <code>Flux</code>:</p>
<ol>
<li><p>On method <code>getAll</code>, 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 <code>Flux</code>.</p>
</li>
<li><p>On method <code>getOne</code>, we request for a single piece of data, for this case we wrap the returned data in <code>Mono</code>.</p>
</li>
</ol>
<p>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 <code>application.properties</code> file.</p>
<pre><code class="lang-ini"><span class="hljs-attr">spring.r2dbc.url</span>=r2dbc:postgresql://postgres@localhost:<span class="hljs-number">5432</span>/reactive
<span class="hljs-attr">logging.level.org.springframework.r2dbc</span>=DEBUG
</code></pre>
<p>The first line will tell spring to connect to a local database with a database name of <code>reactive</code> with <code>r2dbc</code> as its connection protocol.</p>
<p>The second line is a debugging properties so we can see exactly the queries that are running inside our application.</p>
<p>Next, we need to create a <code>schema.sql</code> file to initialize our database table, we can do that using this query:</p>
<pre><code class="lang-sql"><span class="hljs-keyword">CREATE</span> <span class="hljs-keyword">TABLE</span> <span class="hljs-keyword">IF</span> <span class="hljs-keyword">NOT</span> <span class="hljs-keyword">EXISTS</span> <span class="hljs-keyword">member</span> (
    <span class="hljs-keyword">id</span> <span class="hljs-built_in">SERIAL</span> PRIMARY <span class="hljs-keyword">KEY</span>,
    <span class="hljs-keyword">name</span> <span class="hljs-built_in">TEXT</span> <span class="hljs-keyword">NOT</span> <span class="hljs-literal">NULL</span>
);
</code></pre>
<p>we’re gonna save this inside our <code>resources</code> folder.</p>
<p>One last step, because Spring Data R2DBC doesn’t support auto initializing the database with our <code>schema</code>, we have to manually execute this query when we’re starting our application, this is one of the ways to do it:</p>
<p>we can create a bean on our main application to execute <code>schema.sql</code> whenever we run our application.</p>
<pre><code class="lang-java"><span class="hljs-meta">@Bean</span>
<span class="hljs-function">ConnectionFactoryInitializer <span class="hljs-title">initializer</span><span class="hljs-params">(<span class="hljs-meta">@Qualifier("connectionFactory")</span> ConnectionFactory connectionFactory)</span> </span>{
  ConnectionFactoryInitializer initializer = <span class="hljs-keyword">new</span> ConnectionFactoryInitializer();
  initializer.setConnectionFactory(connectionFactory);
  ResourceDatabasePopulator resource =
      <span class="hljs-keyword">new</span> ResourceDatabasePopulator(<span class="hljs-keyword">new</span> ClassPathResource(<span class="hljs-string">"schema.sql"</span>));
  initializer.setDatabasePopulator(resource);
  <span class="hljs-keyword">return</span> initializer;
}
</code></pre>
<p>Now we can finally run our application. When we see into the log, we can see that the application executed our <code>schema.sql</code>.</p>
<pre><code class="lang-plaintext">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 )
</code></pre>
<p>From our example above, we created 2 <code>GET</code> endpoints:</p>
<ol>
<li><p><code>/api/member</code> to get all of our member’s data</p>
</li>
<li><p><code>/api/member/{name}</code> to get a specific member’s data</p>
</li>
</ol>
<p>When we hit the endpoint of our API to get all member on <code>localhost:8080/api/member</code> we can see that the R2DBC executed this SQL</p>
<pre><code class="lang-plaintext">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]
</code></pre>
<p>and when we do a request on <code>localhost:8080/api/member/{memberName}</code>, the app shows that we’re executing a query to get a single record.</p>
<pre><code class="lang-plaintext">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]
</code></pre>
<p>At this point, we have successfully created a fully reactive application with Spring Data R2DBC, with PostgreSQL as our relational database.</p>
<h2 id="heading-conclusion-and-improvements">Conclusion and improvements</h2>
<p>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.</p>
<p>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.</p>
<p>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 <a target="_blank" href="https://github.com/brettwooldridge/HikariCP">HikariCP</a> for our database connection pooling, but on the reactive side, HikariCP is not available, and one of the options is to use <a target="_blank" href="https://github.com/r2dbc/r2dbc-pool">R2DBC Pool</a>.</p>
<p>All in all, R2DBC is a promising technology, allowing us to have a fully reactive application. Even though there are a lot of unknowns, it’s still worth exploring!</p>
<p>If you want to see the full source code, here’s the link to the full repository: <a target="_blank" href="https://github.com/kamalhm/spring-boot-r2dbc"><strong>kamalhm/spring-boot-r2dbc</strong> *An example implementation of Spring Boot R2DBC REST API with PostgreSQL database. Spring Boot 2.4.1.RELEASE Spring Data…*github.com</a></p>
<p>Thanks for reading! :)</p>
]]></content:encoded></item></channel></rss>